1 /* -*- tab-width: 4 -*-
2  *
3  * Electric(tm) VLSI Design System
4  *
5  * File: usrdiacom.cpp
6  * Special command dialogs
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 #include "global.h"
32 #include "egraphics.h"
33 #include "usr.h"
34 #include "drc.h"
35 #include "network.h"
36 #include "usrdiacom.h"
37 #include "usrtrack.h"
38 #include "efunction.h"
39 #include "tecart.h"
40 #include "tecschem.h"
41 #include "tecgen.h"
42 #include "tecmocmos.h"
43 #include "tecmocmossub.h"
44 #include "usredtec.h"
45 #include "eio.h"
46 #include "sim.h"
47 #include "edialogs.h"
48 #include "conlay.h"
49 #include <math.h>
50 
51 #ifdef USEQT
52 #  include <qapplication.h>
53 #  include <qprogressdialog.h>
54 #endif
55 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
56 extern "C" {
57 #endif
58 	extern COMCOMP us_colorwritep, us_colorreadp;
59 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
60 }
61 #endif
62 
63 struct butlist
64 {
65 	UINTBIG value;
66 	INTBIG  button;
67 };
68 
69 /* icons for text and port dialogs */
70 static UCHAR1 us_icon200[] =
71 {
72 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
73 	0200, 0, 0, 0200, 0200, 040, 0, 0200, 0200, 060, 0, 0200, 0203, 0370, 0, 0200,
74 	0200, 060, 0, 0200, 0200, 040, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
75 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
76 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
77 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 010, 0, 0200, 0200, 010, 0, 0200,
78 	0200, 010, 0, 0200, 0200, 010, 0, 0200, 0200, 076, 0, 0200, 0200, 034, 0, 0200,
79 	0200, 010, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0
80 };
81 static UCHAR1 us_icon201[] =
82 {
83 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 010, 0, 0200, 0200, 034, 0, 0200,
84 	0200, 076, 0, 0200, 0200, 010, 0, 0200, 0200, 010, 0, 0200, 0200, 010, 0, 0200,
85 	0200, 010, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
86 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
87 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
88 	0200, 0, 0, 0200, 0200, 0, 010, 0200, 0200, 0, 014, 0200, 0200, 0, 0376, 0200,
89 	0200, 0, 014, 0200, 0200, 0, 010, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
90 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0
91 };
92 static UCHAR1 us_icon202[] =
93 {
94 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
95 	0200, 0, 0, 0200, 0210, 0, 0, 0200, 0230, 0, 0, 0200, 0277, 0200, 0, 0200,
96 	0230, 0, 0, 0200, 0210, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
97 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
98 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
99 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0100, 0200,
100 	0200, 0, 040, 0200, 0200, 0, 022, 0200, 0200, 0, 016, 0200, 0200, 0, 016, 0200,
101 	0200, 0, 036, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0
102 };
103 static UCHAR1 us_icon203[] =
104 {
105 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
106 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0201, 0, 0, 0200,
107 	0202, 0, 0, 0200, 0244, 0, 0, 0200, 0270, 0, 0, 0200, 0270, 0, 0, 0200,
108 	0274, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
109 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 0, 036, 0200, 0200, 0, 016, 0200,
110 	0200, 0, 016, 0200, 0200, 0, 022, 0200, 0200, 0, 040, 0200, 0200, 0, 0100, 0200,
111 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
112 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0
113 };
114 static UCHAR1 us_icon204[] =
115 {
116 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0274, 0, 0, 0200, 0270, 0, 0, 0200,
117 	0270, 0, 0, 0200, 0244, 0, 0, 0200, 0202, 0, 0, 0200, 0201, 0, 0, 0200,
118 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
119 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
120 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0200, 010, 0, 0200, 0200, 034, 0, 0200,
121 	0200, 076, 0, 0200, 0210, 010, 010, 0200, 0230, 010, 014, 0200, 0277, 0200, 0376, 0200,
122 	0230, 010, 014, 0200, 0210, 010, 010, 0200, 0200, 076, 0, 0200, 0200, 034, 0, 0200,
123 	0200, 010, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0
124 };
125 static UCHAR1 us_icon205[] =
126 {
127 	0377, 0377, 0377, 0200, 0200, 0, 0, 0200, 0274, 0, 0, 0200, 0270, 0, 0, 0200,
128 	0270, 0, 0, 0200, 0244, 0, 0, 0200, 0202, 0, 0, 0200, 0201, 0, 0, 0200,
129 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200, 0200, 0, 0, 0200,
130 	0200, 0, 0, 0200, 0200, 0, 0, 0200, 0377, 0377, 0377, 0200, 0, 0, 0, 0,
131 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
135 };
136 #define NUMPORTCHARS 16
137 static CHAR *us_exportcharnames[NUMPORTCHARS] = {N_("Unknown"), N_("Input"), N_("Output"), N_("Bidirectional"),
138 	N_("Power"), N_("Ground"), N_("Reference Output"), N_("Reference Input"), N_("Reference Base"),
139 	N_("Clock"), N_("Clock phase 1"), N_("Clock phase 2"), N_("Clock phase 3"), N_("Clock phase 4"),
140 	N_("Clock phase 5"), N_("Clock phase 6")};
141 static UINTBIG us_exportcharlist[NUMPORTCHARS] = {0, INPORT, OUTPORT, BIDIRPORT, PWRPORT, GNDPORT,
142 	REFOUTPORT, REFINPORT, REFBASEPORT, CLKPORT, C1PORT, C2PORT, C3PORT, C4PORT, C5PORT, C6PORT};
143 static CHAR *us_exportintnames[NUMPORTCHARS] = {x_(""), x_("input"), x_("output"), x_("bidirectional"),
144 	x_("power"), x_("ground"), x_("refout"), x_("refin"), x_("refbase"),
145 	x_("clock"), x_("clock1"), x_("clock2"), x_("clock3"), x_("clock4"), x_("clock5"),
146 	x_("clock6")};
147 static CHAR *us_rotationtypes[4] = {N_("None"), N_("90 degrees counterclockwise"),
148 	N_("180 degrees"), N_("90 degrees clockwise")};
149 static CHAR *us_unitnames[] = {N_("None"), N_("Resistance"), N_("Capacitance"),
150 	N_("Inductance"), N_("Current"), N_("Voltage"), N_("Distance"), N_("Time")};
151 
152 /* the entries in this array must align with the constants in the "INTERNALRESUNITS" field */
153 CHAR *us_resistancenames[4] = {N_("Ohms"), N_("Kilo-ohms"), N_("Mega-ohms"),
154 	N_("Giga-Ohms")};
155 
156 /* the entries in this array must align with the constants in the "INTERNALCAPUNITS" field */
157 CHAR *us_capacitancenames[6] = {N_("Farads"), N_("Milli-farads"), N_("Micro-farads"),
158 	N_("Nano-farads"), N_("Pico-farads"), N_("Femto-farads")};
159 
160 /* the entries in this array must align with the constants in the "INTERNALINDUNITS" field */
161 CHAR *us_inductancenames[4] = {N_("Henrys"), N_("Milli-henrys"), N_("Micro-henrys"),
162 	N_("Nano-henrys")};
163 
164 /* the entries in this array must align with the constants in the "INTERNALCURUNITS" field */
165 CHAR *us_currentnames[3] = {N_("Amps"), N_("Milli-amps"), N_("Micro-amps")};
166 
167 /* the entries in this array must align with the constants in the "INTERNALVOLTUNITS" field */
168 CHAR *us_voltagenames[4] = {N_("Kilo-vols"), N_("Volts"), N_("Milli-volts"),
169 	N_("Micro-volts")};
170 
171 /* the entries in this array must align with the constants in the "INTERNALTIMEUNITS" field */
172 CHAR *us_timenames[6] = {N_("Seconds"), N_("Milli-seconds"), N_("Micro-seconds"),
173 	N_("Nano-seconds"), N_("Pico-seconds"), N_("Femto-seconds")};
174 
175 static INTBIG us_colorvaluelist[25] =
176 {
177 	COLORT1,		/* overlappable 1 */
178 	COLORT2,		/* overlappable 2 */
179 	COLORT3,		/* overlappable 3 */
180 	COLORT4,		/* overlappable 4 */
181 	COLORT5,		/* overlappable 5 */
182 	WHITE,			/* white */
183 	BLACK,			/* black */
184 	RED,			/* red */
185 	BLUE,			/* blue */
186 	GREEN,			/* green */
187 	CYAN,			/* cyan */
188 	MAGENTA,		/* magenta */
189 	YELLOW,			/* yellow */
190 	GRAY,			/* gray */
191 	ORANGE,			/* orange */
192 	PURPLE,			/* purple */
193 	BROWN,			/* brown */
194 	LGRAY,			/* light gray */
195 	DGRAY,			/* dark gray */
196 	LRED,			/* light red */
197 	DRED,			/* dark red */
198 	LGREEN,			/* light green */
199 	DGREEN,			/* dark green */
200 	LBLUE,			/* light blue */
201 	DBLUE			/* dark blue */
202 };
203 
204 static CHAR      *us_lastplacetextmessage = 0;
205 static CHAR      *us_lastfindtextmessage = 0;
206 static CHAR      *us_lastreplacetextmessage = 0;
207 static CHAR      *us_returneddialogstring = 0;
208 static NODEPROTO *us_oldcellprotos;
209 static INTBIG     us_showoldversions;				/* nonzero if cell lists include old versions */
210 static INTBIG     us_showcellibrarycells;			/* nonzero if cell lists include cell-library cells */
211 static INTBIG     us_showonlyrelevantcells;			/* nonzero if cell lists exclude cells from other views */
212 static INTBIG     us_defshowoldversions = 1;		/* default state of "us_showoldversions" */
213 static INTBIG     us_defshowcellibrarycells = 1;	/* default state of "us_showcellibrarycells" */
214 static INTBIG     us_defshowonlyrelevantcells = 0;	/* default state of "us_showonlyrelevantcells" */
215 static LIBRARY   *us_curlib;
216 static void      *us_trackingdialog;				/* dialog when tracking cursor */
217 
218 /* prototypes for local routines */
219 static BOOLEAN    us_oldcelltopofcells(CHAR**);
220 static CHAR      *us_oldcellnextcells(void);
221 static CHAR     **us_languagechoices(void);
222 static void       us_widlendlog(NODEINST *ni);
223 static void       us_resistancedlog(GEOM*, VARIABLE*);
224 static void       us_capacitancedlog(GEOM*, VARIABLE*);
225 static void       us_inductancedlog(GEOM*, VARIABLE*);
226 static void       us_areadlog(NODEINST*);
227 static BOOLEAN    us_showforeignlicense(FILE *io, INTBIG section, INTBIG item, void *dia);
228 static INTBIG     us_makeviewlist(CHAR ***viewlist);
229 static void       us_setpopupface(INTBIG popupitem, INTBIG face, BOOLEAN init, void *dia);
230 static INTBIG     us_getpopupface(INTBIG popupitem, void *dia);
231 static INTBIG     us_scalabletransdlog(void);
232 static CHAR     **us_makelibrarylist(INTBIG *total, LIBRARY *clib, INTBIG *current);
233 static NODEPROTO *us_getselectedcell(void *dia);
234 
235 /*
236  * Routine to free all memory associated with this module.
237  */
us_freediacommemory(void)238 void us_freediacommemory(void)
239 {
240 	if (us_lastplacetextmessage != 0) efree((CHAR *)us_lastplacetextmessage);
241 	if (us_lastfindtextmessage != 0) efree((CHAR *)us_lastfindtextmessage);
242 	if (us_lastreplacetextmessage != 0) efree((CHAR *)us_lastreplacetextmessage);
243 	if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
244 }
245 
246 /*
247  * Routines for listing all cells in library "us_curlib".
248  * If "us_showoldversions" is nonzero, show old versions.
249  * If "us_showcellibrarycells" is nonzero, show cells that are part of cell libraries.
250  * If "us_showonlyrelevantcells" is nonzero, show only cells of the same view as the current.
251  */
us_oldcelltopofcells(CHAR ** c)252 BOOLEAN us_oldcelltopofcells(CHAR **c)
253 {
254 	Q_UNUSED( c );
255 	us_oldcellprotos = us_curlib->firstnodeproto;
256 	return(TRUE);
257 }
258 
us_oldcellnextcells(void)259 CHAR *us_oldcellnextcells(void)
260 {
261 	REGISTER NODEPROTO *thisnp;
262 	REGISTER LIBRARY *savelibrary;
263 	REGISTER VIEW *view;
264 	REGISTER CHAR *ret;
265 
266 	while (us_oldcellprotos != NONODEPROTO)
267 	{
268 		thisnp = us_oldcellprotos;
269 		us_oldcellprotos = us_oldcellprotos->nextnodeproto;
270 		if (us_showoldversions == 0 && thisnp->newestversion != thisnp) continue;
271 		if (us_showcellibrarycells == 0 && (thisnp->userbits&INCELLLIBRARY) != 0)
272 			continue;
273 		if (us_showonlyrelevantcells != 0 && us_curlib->curnodeproto != NONODEPROTO)
274 		{
275 			if (el_curlib->curnodeproto == NONODEPROTO) view = el_unknownview; else
276 				view = el_curlib->curnodeproto->cellview;
277 			if (view != el_unknownview)
278 			{
279 				if (view == el_schematicview)
280 				{
281 					/* schematics: allow schematics or icons */
282 					if (thisnp->cellview != el_schematicview &&
283 						thisnp->cellview != el_iconview) continue;
284 				} else
285 				{
286 					if (thisnp->cellview != view) continue;
287 				}
288 			}
289 		}
290 		savelibrary = el_curlib;
291 		el_curlib = us_curlib;
292 		ret = describenodeproto(thisnp);
293 		el_curlib = savelibrary;
294 		return(ret);
295 	}
296 	return(0);
297 }
298 
299 /*
300  * Helper routine to return a translated array of strings describing the 4 language
301  * choices (none, TCL, LISP, Java).
302  */
us_languagechoices(void)303 CHAR **us_languagechoices(void)
304 {
305 	static CHAR *languages[] = {N_("Not Code"), N_("TCL"), N_("LISP"), N_("Java")};
306 	static CHAR *newlang[4];
307 	REGISTER INTBIG i;
308 
309 #if LANGTCL == 0
310 	languages[1] = N_("TCL (not available)");
311 #endif
312 #if LANGLISP == 0
313 	languages[2] = N_("LISP (not available)");
314 #endif
315 #if LANGJAVA == 0
316 	languages[3] = N_("Java (not available)");
317 #endif
318 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(languages[i]);
319 	return(newlang);
320 }
321 
322 /*
323  * Routine to make a sorted list of libraries and return their names.
324  * Returns the number of libraries in "total".  The index of library "clib"
325  * is returned in "current".
326  */
us_makelibrarylist(INTBIG * total,LIBRARY * clib,INTBIG * current)327 CHAR **us_makelibrarylist(INTBIG *total, LIBRARY *clib, INTBIG *current)
328 {
329 	REGISTER LIBRARY *lib;
330 	REGISTER CHAR **liblist=0;
331 	REGISTER INTBIG i, count;
332 
333 	i = 0;
334 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
335 		if ((lib->userbits&HIDDENLIBRARY) == 0) i++;
336 	*total = i;
337 	*current = -1;
338 	if (i > 0)
339 	{
340 		liblist = (CHAR **)emalloc(i * (sizeof (CHAR *)), el_tempcluster);
341 		if (liblist == 0)
342 		{
343 			*total = 0;
344 			return(0);
345 		}
346 		count = 0;
347 		for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
348 			if ((lib->userbits&HIDDENLIBRARY) == 0) liblist[count++] = lib->libname;
349 		esort(liblist, count, sizeof (CHAR *), sort_stringascending);
350 		for(i=0; i<count; i++)
351 			if (namesame(liblist[i], clib->libname) == 0) *current = i;
352 	}
353 	return(liblist);
354 }
355 
356 /*
357  * Routine to build a list of views in "viewlist" and return its length (0 on error).
358  * The list must be deallocated when done (but not the individual elements).
359  */
us_makeviewlist(CHAR *** viewlist)360 INTBIG us_makeviewlist(CHAR ***viewlist)
361 {
362 	REGISTER INTBIG viewcount, i, firstsview;
363 	REGISTER VIEW *v;
364 
365 	for(viewcount = 0, v = el_views; v != NOVIEW; v = v->nextview) viewcount++;
366 	*viewlist = (CHAR **)emalloc(viewcount * (sizeof (CHAR *)), el_tempcluster);
367 	if (*viewlist == 0) return(0);
368 	for(v = el_views; v != NOVIEW; v = v->nextview) v->temp1 = 0;
369 	i = 0;
370 	(*viewlist)[i++] = el_layoutview->viewname;      el_layoutview->temp1 = 1;
371 	(*viewlist)[i++] = el_schematicview->viewname;   el_schematicview->temp1 = 1;
372 	firstsview = i;
373 	for(v = el_views; v != NOVIEW; v = v->nextview)
374 		if (v->temp1 == 0)
375 			(*viewlist)[i++] = v->viewname;
376 	esort(&(*viewlist)[firstsview], viewcount-firstsview, sizeof (CHAR *), sort_stringascending);
377 	return(viewcount);
378 }
379 
380 /****************************** PROGRESS DIALOGs ******************************/
381 
382 /* Progress (extended) */
383 static DIALOGITEM us_eprogressdialogitems[] =
384 {
385  /*  1 */ {0, {56,8,73,230}, PROGRESS, x_("")},
386  /*  2 */ {0, {32,8,48,230}, MESSAGE, N_("Reading file...")},
387  /*  3 */ {0, {8,8,24,230}, MESSAGE, x_("")}
388 };
389 DIALOG us_eprogressdialog = {{50,75,135,314}, 0, 0, 3, us_eprogressdialogitems, x_("eprogress"), 0};
390 
391 /* Progress (simple) */
392 static DIALOGITEM us_progressdialogitems[] =
393 {
394  /*  1 */ {0, {32,8,49,230}, PROGRESS, x_("")},
395  /*  2 */ {0, {8,8,24,230}, MESSAGE, N_("Reading file...")}
396 };
397 DIALOG us_progressdialog = {{50,75,112,314}, 0, 0, 2, us_progressdialogitems, x_("progress"), 0};
398 
399 /* special items for the "Progress" dialogs: */
400 #define PROG_PROGRESS    1      /* indicator (progress) */
401 #define PROG_LABEL       2      /* label (message) */
402 #define PROG_CAPTION     3      /* capture (message) */
403 
DiaInitProgress(CHAR * label,CHAR * caption)404 void *DiaInitProgress(CHAR *label, CHAR *caption)
405 {
406 #ifdef USEQT
407 	QProgressDialog *d = new QProgressDialog( qApp->mainWidget(), 0, FALSE );
408 	if (caption)
409 	{
410 		QString qcap = QString::fromLocal8Bit( caption );
411 		d->setCaption( qcap );
412 	}
413 	if (!label) label = _("Reading file...");
414 	QString qlab = QString::fromLocal8Bit( label );
415 	d->setLabelText( qlab );
416 	qApp->processEvents();
417 	return d;
418 #else
419 	void *dia;
420 
421 	if (caption != 0)
422 	{
423 		dia = DiaInitDialog(&us_eprogressdialog);
424 		DiaSetText( dia, PROG_CAPTION, caption );
425 	} else
426 	{
427 		dia = DiaInitDialog(&us_progressdialog);
428 	}
429 	if (!label) label = _("Reading file...");
430 	DiaSetText( dia, PROG_LABEL, label );
431 	return(dia);
432 #endif
433 }
434 
DiaSetProgress(void * dia,INTBIG progress,INTBIG totalSteps)435 void DiaSetProgress(void *dia, INTBIG progress, INTBIG totalSteps)
436 {
437 #ifdef USEQT
438 	QProgressDialog *d = (QProgressDialog*)dia;
439 	if (totalSteps != d->totalSteps() || progress == 0)
440 	{
441 		d->setTotalSteps( totalSteps );
442 	}
443 # ifdef MACOSX
444 	else if (progress > 0 && progress < totalSteps &&
445 		progress >= d->progress() && progress < d->progress() + totalSteps/50)
446 	{
447 		return;
448 	}
449 # endif
450 	d->setProgress( progress );
451 	qApp->processEvents();
452 	if (d->wasCancelled()) el_pleasestop = 1;
453 #else
454 	progress = (totalSteps > 0 ? progress*100L/totalSteps : 100);
455 	DiaPercent(dia, 1, progress);
456 #endif
457 }
458 
DiaSetTextProgress(void * dia,CHAR * label)459 void DiaSetTextProgress(void *dia, CHAR *label)
460 {
461 #ifdef USEQT
462 	QProgressDialog *d = (QProgressDialog*)dia;
463 	QString qlab = QString::fromLocal8Bit( label );
464 	d->setLabelText( qlab );
465 	if (d->wasCancelled()) el_pleasestop = 1;
466 #else
467 	DiaSetText(dia, PROG_LABEL, label);
468 #endif
469 }
470 
DiaGetTextProgress(void * dia)471 CHAR *DiaGetTextProgress(void *dia)
472 {
473 #ifdef USEQT
474 	static CHAR buf[300];
475 	QProgressDialog *d = (QProgressDialog*)dia;
476 	QCString str = d->labelText().ascii(); /* Need to localize !! */
477 	estrcpy(buf, str);
478 	return buf;
479 #else
480 	return DiaGetText(dia, PROG_LABEL);
481 #endif
482 }
483 
DiaSetCaptionProgress(void * dia,CHAR * caption)484 void  DiaSetCaptionProgress(void *dia, CHAR *caption)
485 {
486 #ifdef USEQT
487 	QProgressDialog *d = (QProgressDialog*)dia;
488 	QString qcap = QString::fromLocal8Bit( caption );
489 	d->setCaption( qcap );
490 	if (d->wasCancelled()) el_pleasestop = 1;
491 #else
492 	DiaSetText(dia, PROG_CAPTION, caption);
493 #endif
494 }
495 
DiaDoneProgress(void * dia)496 void DiaDoneProgress(void *dia)
497 {
498 #ifdef USEQT
499 	QProgressDialog *d = (QProgressDialog*)dia;
500 	delete d;
501 #else
502 	DiaDoneDialog(dia);
503 #endif
504 }
505 
506 /****************************** 3D DEPTH DIALOG ******************************/
507 
508 /* 3D Depth */
509 static DIALOGITEM us_3ddepthdialogitems[] =
510 {
511  /*  1 */ {0, {552,300,576,380}, BUTTON, N_("OK")},
512  /*  2 */ {0, {552,188,576,268}, BUTTON, N_("Cancel")},
513  /*  3 */ {0, {32,8,404,168}, SCROLL, x_("")},
514  /*  4 */ {0, {32,184,544,388}, USERDRAWN, x_("")},
515  /*  5 */ {0, {412,8,428,88}, MESSAGE, N_("Thickness:")},
516  /*  6 */ {0, {412,96,428,168}, EDITTEXT, x_("0")},
517  /*  7 */ {0, {8,8,24,324}, MESSAGE, x_("")},
518  /*  8 */ {0, {556,9,572,161}, CHECK, N_("Use Perspective")},
519  /*  9 */ {0, {436,8,452,88}, MESSAGE, N_("Height:")},
520  /* 10 */ {0, {436,96,452,168}, EDITTEXT, x_("0")},
521  /* 11 */ {0, {460,8,476,180}, MESSAGE, N_("Separate flat layers by:")},
522  /* 12 */ {0, {480,96,496,168}, EDITTEXT, x_("0")},
523  /* 13 */ {0, {508,28,532,148}, BUTTON, N_("Clean Up")}
524 };
525 static DIALOG us_3ddepthdialog = {{75,75,660,473}, N_("3D Options"), 0, 13, us_3ddepthdialogitems, 0, 0};
526 
527 /* special items for the "3D depth" dialog: */
528 #define D3DD_LAYERLIST   3		/* list of layers (scroll) */
529 #define D3DD_LAYERVIEW   4		/* layer side-view (user item) */
530 #define D3DD_THICKNESS   6		/* layer thickness (edit text) */
531 #define D3DD_TECHNAME    7		/* technology name (message) */
532 #define D3DD_PERSPECTIVE 8		/* user perspective (check) */
533 #define D3DD_HEIGHT      10		/* layer height (edit text) */
534 #define D3DD_FLATSEP     12		/* flat-layer separation (edit text) */
535 #define D3DD_CLEANUP     13		/* clean up (button) */
536 
537 RECTAREA  us_3dheightrect;
538 INTBIG    us_3dcurlayer;
539 float    *us_3dheight;
540 float    *us_3dthickness;
541 INTBIG   *us_3dlayerindex;
542 INTBIG    us_3dlayercount;
543 float     us_3dlowheight, us_3dhighheight;
544 INTBIG    us_3dchanged;
545 
546 static void us_redraw3ddepth(RECTAREA *bigr, void *dia);
547 static void us_3ddepthstroke(INTBIG x, INTBIG y);
548 
us_3ddepthdlog(void)549 INTBIG us_3ddepthdlog(void)
550 {
551 	INTBIG itemHit;
552 	INTBIG x, y;
553 	CHAR line[20];
554 	REGISTER WINDOWPART *w;
555 	REGISTER INTBIG i, j, funct, functp, ypos;
556 	float thickness, height, newthick, newheight;
557 	REGISTER void *infstr, *dia;
558 
559 	/* cache the heights and thicknesses */
560 	us_3dheight = (float *)emalloc(el_curtech->layercount * (sizeof (float)), el_tempcluster);
561 	if (us_3dheight == 0) return(0);
562 	us_3dthickness = (float *)emalloc(el_curtech->layercount * (sizeof (float)), el_tempcluster);
563 	if (us_3dthickness == 0) return(0);
564 	us_3dlayerindex = (INTBIG *)emalloc(el_curtech->layercount * SIZEOFINTBIG, el_tempcluster);
565 	if (us_3dlayerindex == 0) return(0);
566 	for(i=0; i<el_curtech->layercount; i++)
567 	{
568 		if (get3dfactors(el_curtech, i, &us_3dheight[i], &us_3dthickness[i]))
569 		{
570 			us_3dheight[i] = 0.0;
571 			us_3dthickness[i] = 0.0;
572 		}
573 	}
574 
575 	/* determine which layers are useful */
576 	us_3dlayercount = 0;
577 	for(i=0; i<el_curtech->layercount; i++)
578 	{
579 		funct = layerfunction(el_curtech, i);
580 		if ((funct&LFPSEUDO) != 0) continue;
581 		us_3dlayerindex[us_3dlayercount++] = i;
582 	}
583 
584 	/* display the 3D options dialog box */
585 	dia = DiaInitDialog(&us_3ddepthdialog);
586 	if (dia == 0) return(0);
587 	infstr = initinfstr();
588 	addstringtoinfstr(infstr, _("Layer heights for technology "));
589 	addstringtoinfstr(infstr, el_curtech->techname);
590 	DiaSetText(dia, D3DD_TECHNAME, returninfstr(infstr));
591 	if ((us_useroptions&NO3DPERSPECTIVE) == 0)
592 		DiaSetControl(dia, D3DD_PERSPECTIVE, 1);
593 	DiaSetText(dia, D3DD_FLATSEP, x_("1.0"));
594 	DiaDimItem(dia, D3DD_FLATSEP);
595 	DiaDimItem(dia, D3DD_CLEANUP);
596 
597 	/* setup list of layer names */
598 	DiaInitTextDialog(dia, D3DD_LAYERLIST, DiaNullDlogList, DiaNullDlogItem,
599 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
600 	for(i=0; i<us_3dlayercount; i++)
601 		DiaStuffLine(dia, D3DD_LAYERLIST, layername(el_curtech, us_3dlayerindex[i]));
602 	DiaSelectLine(dia, D3DD_LAYERLIST, 0);
603 	us_3dcurlayer = us_3dlayerindex[0];
604 	esnprintf(line, 20, x_("%g"), us_3dthickness[us_3dcurlayer]);
605 	DiaSetText(dia, D3DD_THICKNESS, line);
606 	esnprintf(line, 20, x_("%g"), us_3dheight[us_3dcurlayer]);
607 	DiaSetText(dia, D3DD_HEIGHT, line);
608 
609 	/* setup layer height area */
610 	DiaItemRect(dia, D3DD_LAYERVIEW, &us_3dheightrect);
611 	DiaRedispRoutine(dia, D3DD_LAYERVIEW, us_redraw3ddepth);
612 	for(i=0; i<el_curtech->layercount; i++)
613 	{
614 		height = us_3dheight[i] * 2.0f;
615 		thickness = us_3dthickness[i] * 2.0f;
616 		if (i == 0)
617 		{
618 			us_3dlowheight = height - thickness/2.0f;
619 			us_3dhighheight = height + thickness/2.0f;
620 		} else
621 		{
622 			if (height - thickness/2.0f < us_3dlowheight)
623 				us_3dlowheight = height - thickness/2.0f;
624 			if (height + thickness/2.0f > us_3dhighheight)
625 				us_3dhighheight = height + thickness/2.0f;
626 		}
627 	}
628 	us_3dlowheight -= 4.0f;
629 	us_3dhighheight += 4.0f;
630 	us_redraw3ddepth(&us_3dheightrect, dia);
631 
632 	/* loop until done */
633 	us_3dchanged = 0;
634 	for(;;)
635 	{
636 		itemHit = DiaNextHit(dia);
637 		if (itemHit == CANCEL) break;
638 		if (itemHit == OK) break;
639 		if (itemHit == D3DD_LAYERLIST)
640 		{
641 			j = DiaGetCurLine(dia, D3DD_LAYERLIST);
642 			us_3dcurlayer = us_3dlayerindex[j];
643 			esnprintf(line, 20, x_("%g"), us_3dthickness[us_3dcurlayer]);
644 			DiaSetText(dia, D3DD_THICKNESS, line);
645 			esnprintf(line, 20, x_("%g"), us_3dheight[us_3dcurlayer]);
646 			DiaSetText(dia, D3DD_HEIGHT, line);
647 			us_redraw3ddepth(&us_3dheightrect, dia);
648 			continue;
649 		}
650 		if (itemHit == D3DD_THICKNESS)
651 		{
652 			j = DiaGetCurLine(dia, D3DD_LAYERLIST);
653 			us_3dcurlayer = us_3dlayerindex[j];
654 			newthick = (float)eatof(DiaGetText(dia, D3DD_THICKNESS));
655 			if (newthick == us_3dthickness[us_3dcurlayer]) continue;
656 			us_3dchanged++;
657 			us_3dthickness[us_3dcurlayer] = newthick;
658 			us_redraw3ddepth(&us_3dheightrect, dia);
659 			continue;
660 		}
661 		if (itemHit == D3DD_HEIGHT)
662 		{
663 			j = DiaGetCurLine(dia, D3DD_LAYERLIST);
664 			us_3dcurlayer = us_3dlayerindex[j];
665 			newheight = (float)eatof(DiaGetText(dia, D3DD_HEIGHT));
666 			if (newheight == us_3dheight[us_3dcurlayer]) continue;
667 			us_3dchanged++;
668 			us_3dheight[us_3dcurlayer] = newheight;
669 			us_redraw3ddepth(&us_3dheightrect, dia);
670 			continue;
671 		}
672 		if (itemHit == D3DD_LAYERVIEW)
673 		{
674 			DiaGetMouse(dia, &x, &y);
675 			ypos = (INTBIG)(us_3dheightrect.bottom - (us_3dheight[us_3dcurlayer]*2.0 - us_3dlowheight) *
676 				(us_3dheightrect.bottom - us_3dheightrect.top) / (us_3dhighheight - us_3dlowheight));
677 			if (abs(ypos-y) > 5)
678 			{
679 				/* selecting a new layer */
680 				for(i=0; i<us_3dlayercount; i++)
681 				{
682 					j = us_3dlayerindex[i];
683 					ypos = (INTBIG)(us_3dheightrect.bottom - (us_3dheight[j]*2.0 - us_3dlowheight) *
684 						(us_3dheightrect.bottom - us_3dheightrect.top) / (us_3dhighheight - us_3dlowheight));
685 					if (abs(ypos-y) <= 5) break;
686 				}
687 				if (i >= us_3dlayercount) continue;
688 				us_3dcurlayer = us_3dlayerindex[i];
689 				DiaSelectLine(dia, D3DD_LAYERLIST, i);
690 				esnprintf(line, 20, x_("%g"), us_3dthickness[us_3dcurlayer]);
691 				DiaSetText(dia, D3DD_THICKNESS, line);
692 				esnprintf(line, 20, x_("%g"), us_3dheight[us_3dcurlayer]);
693 				DiaSetText(dia, D3DD_HEIGHT, line);
694 				us_redraw3ddepth(&us_3dheightrect, dia);
695 			} else
696 			{
697 				/* clicking on already-selected layer: drag it */
698 				us_trackingdialog = dia;
699 				DiaTrackCursor(dia, us_3ddepthstroke);
700 			}
701 			continue;
702 		}
703 		if (itemHit == D3DD_PERSPECTIVE)
704 		{
705 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
706 			continue;
707 		}
708 	}
709 
710 	if (itemHit != CANCEL)
711 	{
712 		/* copy regular layers to pseudo-layers */
713 		for(i=0; i<el_curtech->layercount; i++)
714 		{
715 			functp = layerfunction(el_curtech, i);
716 			if ((functp&LFPSEUDO) == 0) continue;
717 
718 			/* pseudo layer found: look for real one */
719 			for(j=0; j<el_curtech->layercount; j++)
720 			{
721 				funct = layerfunction(el_curtech, j);
722 				if ((funct&LFPSEUDO) != 0) continue;
723 				if ((functp & ~LFPSEUDO) == funct)
724 				{
725 					us_3dheight[i] = us_3dheight[j];
726 					us_3dthickness[i] = us_3dthickness[j];
727 					break;
728 				}
729 			}
730 		}
731 		set3dheight(el_curtech, us_3dheight);
732 		set3dthickness(el_curtech, us_3dthickness);
733 		j = us_useroptions;
734 		if (DiaGetControl(dia, D3DD_PERSPECTIVE) == 0) j |= NO3DPERSPECTIVE; else j &= ~NO3DPERSPECTIVE;
735 		if (j != us_useroptions)
736 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, j, VINTEGER);
737 	}
738 	DiaDoneDialog(dia);
739 	efree((CHAR *)us_3dheight);
740 	efree((CHAR *)us_3dthickness);
741 	if (itemHit != CANCEL)
742 	{
743 		for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
744 		{
745 			if ((w->state&WINDOWTYPE) != DISP3DWINDOW) continue;
746 			if (w->redisphandler != 0) (*w->redisphandler)(w);
747 		}
748 	}
749 	return(0);
750 }
751 
us_redraw3ddepth(RECTAREA * bigr,void * dia)752 void us_redraw3ddepth(RECTAREA *bigr, void *dia)
753 {
754 	REGISTER INTBIG i, ypos1, ypos2, ypos, layer;
755 	float height, thickness;
756 	INTBIG wid, hei;
757 	CHAR *pt;
758 
759 	DiaFrameRect(dia, D3DD_LAYERVIEW, bigr);
760 	for(i=0; i<us_3dlayercount; i++)
761 	{
762 		layer = us_3dlayerindex[i];
763 		height = us_3dheight[layer] * 2.0f;
764 		thickness = us_3dthickness[layer] * 2.0f;
765 		ypos = (INTBIG)(bigr->bottom - (height - us_3dlowheight) *
766 			(bigr->bottom - bigr->top) / (us_3dhighheight - us_3dlowheight));
767 		if (layer == us_3dcurlayer)
768 		{
769 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left, ypos, bigr->left+8, ypos, DLMODEON);
770 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+4, ypos-4, bigr->left+4, ypos+4, DLMODEON);
771 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left, ypos-4, bigr->left+8, ypos+4, DLMODEON);
772 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+8, ypos-4, bigr->left, ypos+4, DLMODEON);
773 		}
774 		if (thickness == 0)
775 		{
776 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+10, ypos, bigr->left+70, ypos, DLMODEON);
777 		} else
778 		{
779 			ypos1 = (INTBIG)(bigr->bottom - (height - thickness/2 - us_3dlowheight) *
780 				(bigr->bottom - bigr->top) / (us_3dhighheight - us_3dlowheight) - 2.0f);
781 			ypos2 = (INTBIG)(bigr->bottom - (height + thickness/2 - us_3dlowheight) *
782 				(bigr->bottom - bigr->top) / (us_3dhighheight - us_3dlowheight) + 2.0f);
783 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+10, ypos1, bigr->left+40, ypos1, DLMODEON);
784 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+40, ypos1, bigr->left+50, ypos, DLMODEON);
785 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+40, ypos2, bigr->left+50, ypos, DLMODEON);
786 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+10, ypos2, bigr->left+40, ypos2, DLMODEON);
787 			DiaDrawLine(dia, D3DD_LAYERVIEW, bigr->left+50, ypos, bigr->left+70, ypos, DLMODEON);
788 		}
789 		pt = layername(el_curtech, layer);
790 		DiaGetTextInfo(dia, pt, &wid, &hei);
791 		DiaPutText(dia, D3DD_LAYERVIEW, pt, bigr->left+70, ypos - hei/2);
792 	}
793 }
794 
us_3ddepthstroke(INTBIG x,INTBIG y)795 void us_3ddepthstroke(INTBIG x, INTBIG y)
796 {
797 	Q_UNUSED( x );
798 	REGISTER float height;
799 	CHAR line[20];
800 
801 	height = ((us_3dheightrect.bottom - y) * (us_3dhighheight - us_3dlowheight) +
802 		(us_3dheightrect.bottom - us_3dheightrect.top)/2.0f) /
803 		(us_3dheightrect.bottom - us_3dheightrect.top) + us_3dlowheight;
804 	if (us_3dheight[us_3dcurlayer] == height / 2.0f) return;
805 	us_3dchanged++;
806 	us_3dheight[us_3dcurlayer] = height / 2.0f;
807 	esnprintf(line, 20, x_("%g"), us_3dheight[us_3dcurlayer]);   DiaSetText(us_trackingdialog, D3DD_HEIGHT, line);
808 	us_redraw3ddepth(&us_3dheightrect, us_trackingdialog);
809 }
810 
811 /****************************** ABOUT ELECTRIC DIALOG ******************************/
812 
813 /*
814  * the list of contributors to Electric (not including Steven M. Rubin)
815  */
816 HELPERS us_castofthousands[] =
817 {
818 	{x_("Philip Attfield"),			N_("Box merging")},
819 	{x_("Brett Bissinger"),		    N_("Node extraction")},
820 	{x_("Ron Bolton"),				N_("Mathematical help")},
821 	{x_("Robert Bosnyak"),			N_("Pads library")},
822 	{x_("Mark Brinsmead"),			N_("Mathematical help")},
823 	{x_("Stefano Concina"),			N_("Polygon clipping")},
824 	{x_("Jonathan Gainsley"),		N_("Testing and design")},
825 	{x_("Peter Gallant"),			N_("ALS simulator")},
826 	{x_("R. Brian Gardiner"),		N_("Electric lifeline")},
827 	{x_("T. J. Goodman"),			N_("Texsim output")},
828 	{x_("Gerrit Groenewold"),		N_("SPICE parts")},
829 	{x_("David Groulx"),		    N_("Node extraction")},
830 	{x_("D. Guptill"),			    N_("X-window help")},
831 	{x_("David Harris"),			N_("Color PostScript output")},
832 	{x_("Robert Hon"),				N_("CIF input parser")},
833 	{x_("Jason Imada"),				N_("ROM generator")},
834 	{x_("Sundaravarathan Iyengar"),	N_("nMOS PLA generator")},
835 	{x_("Allan Jost"),				N_("VHDL compiler help, X-window help")},
836 	{x_("Wallace Kroeker"),			N_("Digital filter technology, CMOS PLA generator")},
837 	{x_("Andrew Kostiuk"),			N_("VHDL compiler, Silicon Compiler")},
838 	{x_("Oliver Laumann"),			N_("ELK Lisp")},
839 	{x_("Glen Lawson"),				N_("Maze routing, GDS input, EDIF I/O")},
840 	{x_("Frank Lee"),				N_("ROM generator")},
841 	{x_("Neil Levine"),				N_("PADS output")},
842 	{x_("David Lewis"),				N_("Flat DRC checking")},
843 	{x_("Erwin Liu"),				N_("Schematic and Round CMOS technology help")},
844 	{x_("Dick Lyon"),				N_("MOSIS and Round CMOS technology help")},
845 	{x_("John Mohammed"),			N_("Mathematical help")},
846 	{x_("Mark Moraes"),				N_("Hierarchical DRC, X-window help")},
847 	{x_("Dmitry Nadezhin"),			N_("Qt port, simulation, networks, optimizations, development")},
848 	{x_("Sid Penstone"),			N_("SPICE, SILOS, GDS, Box merging, technologies")},
849 	{x_("J. P. Polonovski"),		N_("Memory allocation help")},
850 	{x_("Kevin Ryan"),			    N_("X-window help")},
851 	{x_("Nora Ryan"),				N_("Compaction, technology conversion")},
852 	{x_("Miguel Saro"),				N_("French translation")},
853 	{x_("Brent Serbin"),			N_("ALS simulator")},
854 	{x_("Lyndon Swab"),				N_("HPGL output, SPICE output help, technologies")},
855 	{x_("Brian W. Thomson"),		N_("Mimic stitcher, RSIM interface")},
856 	{x_("Burnie West"),				N_("Bipolar technology, EDIF output help")},
857 	{x_("Telle Whitney"),			N_("River router")},
858 	{x_("Rob Winstanley"),			N_("CIF input, RNL output")},
859 	{x_("Russell Wright"),			N_("SDF input, miscellaneous help")},
860 	{x_("David J. Yurach"),			N_("VHDL help")},
861 	{0, 0}
862 };
863 
864 CHAR *us_gnucopying[] =
865 {
866 	x_("TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION"),
867 	x_(""),
868 	x_("0. This License applies to any program or other work which contains a notice placed by"),
869 	x_("the copyright holder saying it may be distributed under the terms of this General"),
870 	x_("Public License. The 'Program', below, refers to any such program or work, and a"),
871 	x_("'work based on the Program' means either the Program or any derivative work under"),
872 	x_("copyright law: that is to say, a work containing the Program or a portion of it,"),
873 	x_("either verbatim or with modifications and/or translated into another language."),
874 	x_("(Hereinafter, translation is included without limitation in the term 'modification'.)"),
875 	x_("Each licensee is addressed as 'you'."),
876 	x_(""),
877 	x_("Activities other than copying, distribution and modification are not covered by this"),
878 	x_("License; they are outside its scope. The act of running the Program is not restricted,"),
879 	x_("and the output from the Program is covered only if its contents constitute a work based"),
880 	x_("on the Program (independent of having been made by running the Program). Whether that"),
881 	x_("is true depends on what the Program does."),
882 	x_(""),
883 	x_("1. You may copy and distribute verbatim copies of the Program's source code as you"),
884 	x_("receive it, in any medium, provided that you conspicuously and appropriately publish"),
885 	x_("on each copy an appropriate copyright notice and disclaimer of warranty; keep intact"),
886 	x_("all the notices that refer to this License and to the absence of any warranty; and"),
887 	x_("give any other recipients of the Program a copy of this License along with the Program."),
888 	x_(""),
889 	x_("You may charge a fee for the physical act of transferring a copy, and you may at your"),
890 	x_("option offer warranty protection in exchange for a fee."),
891 	x_(""),
892 	x_("2. You may modify your copy or copies of the Program or any portion of it, thus forming"),
893 	x_("a work based on the Program, and copy and distribute such modifications or work under"),
894 	x_("the terms of Section 1 above, provided that you also meet all of these conditions:"),
895 	x_(""),
896 	x_("*	a) You must cause the modified files to carry prominent notices stating that you"),
897 	x_("	changed the files and the date of any change."),
898 	x_(""),
899 	x_("*	b) You must cause any work that you distribute or publish, that in whole or"),
900 	x_("	in part contains or is derived from the Program or any part thereof, to be licensed"),
901 	x_("	as a whole at no charge to all third parties under the terms of this License."),
902 	x_(""),
903 	x_("*	c) If the modified program normally reads commands interactively when run, you"),
904 	x_("	must cause it, when started running for such interactive use in the most ordinary"),
905 	x_("	way, to print or display an announcement including an appropriate copyright notice"),
906 	x_("	and a notice that there is no warranty (or else, saying that you provide a warranty)"),
907 	x_("	and that users may redistribute the program under these conditions, and telling the"),
908 	x_("	user how to view a copy of this License. (Exception: if the Program itself is"),
909 	x_("	interactive but does not normally print such an announcement, your work based on the"),
910 	x_("	Program is not required to print an announcement.)"),
911 	x_(""),
912 	x_("These requirements apply to the modified work as a whole. If identifiable sections"),
913 	x_("of that work are not derived from the Program, and can be reasonably considered independent"),
914 	x_("and separate works in themselves, then this License, and its terms, do not apply to those"),
915 	x_("sections when you distribute them as separate works. But when you distribute the same"),
916 	x_("sections as part of a whole which is a work based on the Program, the distribution of"),
917 	x_("the whole must be on the terms of this License, whose permissions for other licensees"),
918 	x_("extend to the entire whole, and thus to each and every part regardless of who wrote it."),
919 	x_(""),
920 	x_("Thus, it is not the intent of this section to claim rights or contest your rights to"),
921 	x_("work written entirely by you; rather, the intent is to exercise the right to control"),
922 	x_("the distribution of derivative or collective works based on the Program."),
923 	x_(""),
924 	x_("In addition, mere aggregation of another work not based on the Program with the Program"),
925 	x_("(or with a work based on the Program) on a volume of a storage or distribution medium"),
926 	x_("does not bring the other work under the scope of this License."),
927 	x_(""),
928 	x_("3. You may copy and distribute the Program (or a work based on it, under Section 2)"),
929 	x_("in object code or executable form under the terms of Sections 1 and 2 above provided"),
930 	x_("that you also do one of the following:"),
931 	x_(""),
932 	x_("*	a) Accompany it with the complete corresponding machine-readable source code,"),
933 	x_("which must be distributed under the terms of Sections 1 and 2 above on a medium"),
934 	x_("customarily used for software interchange; or,"),
935 	x_(""),
936 	x_("*	b) Accompany it with a written offer, valid for at least three years, to give"),
937 	x_("any third party, for a charge no more than your cost of physically performing source"),
938 	x_("distribution, a complete machine-readable copy of the corresponding source code,"),
939 	x_("to be distributed under the terms of Sections 1 and 2 above on a medium customarily"),
940 	x_("used for software interchange; or,"),
941 	x_(""),
942 	x_("*	c) Accompany it with the information you received as to the offer to distribute"),
943 	x_("corresponding source code. (This alternative is allowed only for noncommercial"),
944 	x_("distribution and only if you received the program in object code or executable"),
945 	x_("form with such an offer, in accord with Subsection b above.)"),
946 	x_(""),
947 	x_("The source code for a work means the preferred form of the work for making"),
948 	x_("modifications to it. For an executable work, complete source code means all"),
949 	x_("the source code for all modules it contains, plus any associated interface"),
950 	x_("definition files, plus the scripts used to control compilation and installation"),
951 	x_("of the executable. However, as a special exception, the source code distributed"),
952 	x_("need not include anything that is normally distributed (in either source or binary"),
953 	x_("form) with the major components (compiler, kernel, and so on) of the operating"),
954 	x_("system on which the executable runs, unless that component itself accompanies the executable."),
955 	x_(""),
956 	x_("If distribution of executable or object code is made by offering access to copy"),
957 	x_("from a designated place, then offering equivalent access to copy the source code"),
958 	x_("from the same place counts as distribution of the source code, even though third"),
959 	x_("parties are not compelled to copy the source along with the object code."),
960 	x_(""),
961 	x_("4. You may not copy, modify, sublicense, or distribute the Program except as"),
962 	x_("expressly provided under this License. Any attempt otherwise to copy, modify,"),
963 	x_("sublicense or distribute the Program is void, and will automatically terminate your"),
964 	x_("rights under this License. However, parties who have received copies, or rights,"),
965 	x_("from you under this License will not have their licenses terminated so long as"),
966 	x_("such parties remain in full compliance."),
967 	x_(""),
968 	x_("5. You are not required to accept this License, since you have not signed it."),
969 	x_("However, nothing else grants you permission to modify or distribute the Program or"),
970 	x_("its derivative works. These actions are prohibited by law if you do not accept this"),
971 	x_("License. Therefore, by modifying or distributing the Program (or any work based on"),
972 	x_("the Program), you indicate your acceptance of this License to do so, and all its"),
973 	x_("terms and conditions for copying, distributing or modifying the Program or works based on it."),
974 	x_(""),
975 	x_("6. Each time you redistribute the Program (or any work based on the Program),"),
976 	x_("the recipient automatically receives a license from the original licensor to copy,"),
977 	x_("distribute or modify the Program subject to these terms and conditions. You may not"),
978 	x_("impose any further restrictions on the recipients' exercise of the rights granted"),
979 	x_("herein. You are not responsible for enforcing compliance by third parties to this License."),
980 	x_(""),
981 	x_("7. If, as a consequence of a court judgment or allegation of patent infringement"),
982 	x_("or for any other reason (not limited to patent issues), conditions are imposed"),
983 	x_("on you (whether by court order, agreement or otherwise) that contradict the conditions"),
984 	x_("of this License, they do not excuse you from the conditions of this License. If you"),
985 	x_("cannot distribute so as to satisfy simultaneously your obligations under this"),
986 	x_("License and any other pertinent obligations, then as a consequence you may not"),
987 	x_("distribute the Program at all. For example, if a patent license would not permit"),
988 	x_("royalty-free redistribution of the Program by all those who receive copies directly"),
989 	x_("or indirectly through you, then the only way you could satisfy both it and this"),
990 	x_("License would be to refrain entirely from distribution of the Program."),
991 	x_(""),
992 	x_("If any portion of this section is held invalid or unenforceable under any"),
993 	x_("particular circumstance, the balance of the section is intended to apply and"),
994 	x_("the section as a whole is intended to apply in other circumstances."),
995 	x_(""),
996 	x_("It is not the purpose of this section to induce you to infringe any patents"),
997 	x_("or other property right claims or to contest validity of any such claims; this"),
998 	x_("section has the sole purpose of protecting the integrity of the free software"),
999 	x_("distribution system, which is implemented by public license practices. Many"),
1000 	x_("people have made generous contributions to the wide range of software distributed"),
1001 	x_("through that system in reliance on consistent application of that system; it is"),
1002 	x_("up to the author/donor to decide if he or she is willing to distribute software"),
1003 	x_("through any other system and a licensee cannot impose that choice."),
1004 	x_(""),
1005 	x_("This section is intended to make thoroughly clear what is believed to be a"),
1006 	x_("consequence of the rest of this License."),
1007 	x_(""),
1008 	x_("8. If the distribution and/or use of the Program is restricted in certain"),
1009 	x_("countries either by patents or by copyrighted interfaces, the original copyright"),
1010 	x_("holder who places the Program under this License may add an explicit geographical"),
1011 	x_("distribution limitation excluding those countries, so that distribution is permitted"),
1012 	x_("only in or among countries not thus excluded. In such case, this License incorporates"),
1013 	x_("the limitation as if written in the body of this License."),
1014 	x_(""),
1015 	x_("9. The Free Software Foundation may publish revised and/or new versions of the"),
1016 	x_("General Public License from time to time. Such new versions will be similar in"),
1017 	x_("spirit to the present version, but may differ in detail to address new problems"),
1018 	x_("or concerns."),
1019 	x_(""),
1020 	x_("Each version is given a distinguishing version number. If the Program specifies"),
1021 	x_("a version number of this License which applies to it and 'any later version',"),
1022 	x_("you have the option of following the terms and conditions either of that version"),
1023 	x_("or of any later version published by the Free Software Foundation. If the Program"),
1024 	x_("does not specify a version number of this License, you may choose any version ever"),
1025 	x_("published by the Free Software Foundation."),
1026 	x_(""),
1027 	x_("10. If you wish to incorporate parts of the Program into other free programs"),
1028 	x_("whose distribution conditions are different, write to the author to ask for"),
1029 	x_("permission. For software which is copyrighted by the Free Software Foundation,"),
1030 	x_("write to the Free Software Foundation; we sometimes make exceptions for this."),
1031 	x_("Our decision will be guided by the two goals of preserving the free status of"),
1032 	x_("all derivatives of our free software and of promoting the sharing and reuse of"),
1033 	x_("software generally."),
1034 	0
1035 };
1036 CHAR *us_gnuwarranty[] =
1037 {
1038 	x_("NO WARRANTY"),
1039 	x_(""),
1040 	x_("11. Because the program is licensed free of charge, there is no warranty for the"),
1041 	x_("program, to the extent permitted by applicable law. Except when otherwise stated"),
1042 	x_("in writing the copyright holders and/or other parties provide the program 'as is'"),
1043 	x_("without warranty of any kind, either expressed or implied, including, but not"),
1044 	x_("limited to, the implied warranties of merchantability and fitness for a particular"),
1045 	x_("purpose. The entire risk as to the quality and performance of the program is with you."),
1046 	x_("Should the program prove defective, you assume the cost of all necessary servicing,"),
1047 	x_("repair or correction."),
1048 	x_(""),
1049 	x_("12. In no event unless required by applicable law or agreed to in writing will any"),
1050 	x_("copyright holder, or any other party who may modify and/or redistribute the program"),
1051 	x_("as permitted above, be liable to you for damages, including any general, special,"),
1052 	x_("incidental or consequential damages arising out of the use or inability to use the"),
1053 	x_("program (including but not limited to loss of data or data being rendered inaccurate"),
1054 	x_("or losses sustained by you or third parties or a failure of the program to operate"),
1055 	x_("with any other programs), even if such holder or other party has been advised of"),
1056 	x_("the possibility of such damages."),
1057 	0
1058 };
1059 
1060 /* icons for the "About Electric" dialog */
1061 
1062 /* North America version */
1063 static UCHAR1 us_icon130namerica[] =
1064 {
1065 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1066 	0,03,0377,0377, 0,07,0377,0377, 0,017,0377,0377, 0,034,0,0,
1067 	0,070,0,0, 0,0160,0,0, 0,0340,0,0, 01,0300,0,0,
1068 	03,0200,0,0, 03,0,0,0, 07,0,0,0, 06,0,0,0,
1069 	016,03,0374,0, 014,03,0374,0, 034,03,0374,0, 030,03,0374,0,
1070 	070,03,0374,0, 060,03,0374,0, 0160,03,0374,0, 0140,03,0374,0,
1071 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1072 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1073 };
1074 static UCHAR1 us_icon131namerica[] =
1075 {
1076 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1077 	0377,0377,0300,0, 0377,0377,0340,0, 0377,0377,0360,0, 0,0,070,0,
1078 	0,0,034,0, 0,0,016,0, 0,0,07,0, 0,0,03,0200,
1079 	0,0,01,0300, 0,0,0,0300, 0,0,0,0340, 0,0,0,0140,
1080 	0,077,0300,0160, 0,077,0300,060, 0,077,0300,070, 0,077,0300,030,
1081 	0,077,0300,034, 0,077,0300,014, 0,077,0300,016, 0,077,0300,06,
1082 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1083 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1084 };
1085 static UCHAR1 us_icon129namerica[] =
1086 {
1087 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1088 	0340,03,0374,0, 0340,03,0374,0, 0340,0,0,0, 0340,0,0,0,
1089 	0140,0,0,03, 0160,0,0,07, 060,0,0,017, 070,0,0,037,
1090 	030,0,0,077, 034,0,0,077, 014,0,0,077, 016,0,0,077,
1091 	06,0,0,077, 07,0,0,077, 03,0,0,077, 03,0200,0,077,
1092 	01,0300,0,0, 0,0340,0,0, 0,0160,0,0, 0,070,0,0,
1093 	0,034,0,0, 0,017,0377,0377, 0,07,0377,0377, 0,03,0377,0377,
1094 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1095 };
1096 static UCHAR1 us_icon132namerica[] =
1097 {
1098 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1099 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1100 	0300,0,0,06, 0340,0,0,016, 0360,0,0,014, 0370,0,0,034,
1101 	0374,0,0,030, 0374,0,0,070, 0374,0,0,060, 0374,0,0,0160,
1102 	0374,0,0,0140, 0374,0,0,0340, 0374,0,0,0300, 0374,0,01,0300,
1103 	0,0,03,0200, 0,0,07,0, 0,0,016,0, 0,0,034,0,
1104 	0,0,070,0, 0377,0377,0360,0, 0377,0377,0340,0, 0377,0377,0300,0,
1105 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1106 };
1107 
1108 /* Australian/New Zealand version */
1109 static UCHAR1 us_icon130ausnz[] =
1110 {
1111 	0,0377,0377,0377, 07,0377,0377,0377, 017,0377,0377,0377, 037,0300,0,0,
1112 	076,0,0,0, 0174,0,0,0, 0170,0,0,0, 0160,0,0,0,
1113 	0360,0,0,0, 0360,0,070,0, 0340,0,0176,0, 0340,0,0377,0,
1114 	0340,0,0377,0, 0340,01,0376,0, 0340,03,0376,0, 0340,03,0374,0,
1115 	0340,07,0370,0, 0340,07,0370,0, 0340,017,0360,0, 0340,037,0360,0,
1116 	0340,037,0340,0, 0340,077,0340,0, 0340,077,0300,0, 0340,077,0200,0,
1117 	0340,077,0200,0, 0340,017,0,0, 0340,0,0,0, 0340,0,0,0,
1118 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1119 };
1120 static UCHAR1 us_icon131ausnz[] =
1121 {
1122 	0377,0377,0377,0, 0377,0377,0377,0340, 0377,0377,0377,0360, 0,0,03,0370,
1123 	0,0,0,0174, 0,0,0,076, 0,0,0,036, 0,0,0,016,
1124 	0,0,0,017, 0,017,0,017, 0,037,0200,07, 0,0177,0200,07,
1125 	0,0177,0300,07, 0,0177,0300,07, 0,077,0340,07, 0,037,0340,07,
1126 	0,037,0360,07, 0,017,0360,07, 0,017,0370,07, 0,07,0370,07,
1127 	0,03,0374,07, 0,03,0376,07, 0,01,0377,07, 0,01,0376,07,
1128 	0,0,0376,07, 0,0,0374,07, 0,0,0160,07, 0,0,0,07,
1129 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1130 };
1131 static UCHAR1 us_icon129ausnz[] =
1132 {
1133 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1134 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1135 	0340,0,0,0, 0340,0,0,03, 0340,0,0,07, 0340,0,0,07,
1136 	0340,0,0,07, 0340,0,0,07, 0340,0,0,07, 0340,0,0,07,
1137 	0340,0,0,07, 0340,0,0,07, 0340,0,0,07, 0340,0,0,07,
1138 	0340,0,0,07, 0340,0,0,07, 0360,0,0,07, 0360,0,0,07,
1139 	0160,0,0,07, 0170,0,0,07, 0174,0,0,03, 076,0,0,0,
1140 	037,0300,0,0, 017,0377,0377,0377, 07,0377,0377,0377, 0,0377,0377,0377,
1141 };
1142 static UCHAR1 us_icon132ausnz[] =
1143 {
1144 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1145 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1146 	0,0,0,07, 0340,0,0,07, 0360,0,0,07, 0360,0,0,07,
1147 	0360,0,0,07, 0360,0,0,07, 0360,0,0,07, 0360,0,0,07,
1148 	0360,0,0,07, 0360,0,0,07, 0360,0,0,07, 0360,0,0,07,
1149 	0360,0,0,07, 0360,0,0,07, 0360,0,0,017, 0360,0,0,017,
1150 	0360,0,0,016, 0360,0,0,036, 0340,0,0,076, 0,0,0,0174,
1151 	0,0,03,0370, 0377,0377,0377,0360, 0377,0377,0377,0340, 0377,0377,0377,0,
1152 };
1153 
1154 /* European version */
1155 static UCHAR1 us_icon130europe[] =
1156 {
1157 	0,0,0,037, 0,0,0,037, 0,0,01,0377, 0,0,017,0377,
1158 	0,0,0177,0377, 0,01,0377,07, 0,07,0370,07, 0,017,0300,07,
1159 	0,037,0,07, 0,074,0,07, 0,0170,0,07, 0,0360,0,03,
1160 	01,0340,0,03, 03,0300,0,0, 03,0200,0,0, 07,0200,0,0,
1161 	07,0,0,0, 017,0,0,0, 017,0,0,0, 017,0,0,0,
1162 	037,0,0,0, 037,0,0,0, 037,0,0,0, 077,0,0,0,
1163 	077,0,0,0, 077,0,0,0, 077,0,0,0, 0377,01,0340,03,
1164 	0377,07,0370,016, 0340,07,0370,014, 0340,017,0374,032, 0340,017,0374,021,
1165 };
1166 static UCHAR1 us_icon131europe[] =
1167 {
1168 	0370,0,0,0, 0370,0,0,0, 0377,0200,0,0, 0377,0360,0,0,
1169 	0377,0376,0,0, 0340,0377,0200,0, 0340,037,0340,0, 0340,03,0360,0,
1170 	0340,0,0370,0, 0340,0,074,0, 0340,0,036,0, 0300,0,017,0,
1171 	0300,0,07,0200, 0,0,03,0300, 0,0,01,0300, 0,0,01,0340,
1172 	0,0,0,0340, 0,0,0,0360, 0,0,0,0360, 0,0,0,0360,
1173 	0,0,0,0370, 0,0,0,0370, 0,0,0,0370, 0,0,0,0374,
1174 	0,0,0,0374, 0,0,0,0374, 0,0,0,0374, 0300,07,0200,0377,
1175 	0160,037,0340,0377, 020,037,0340,07, 030,077,0360,07, 010,077,0360,07,
1176 };
1177 static UCHAR1 us_icon129europe[] =
1178 {
1179 	0340,017,0374,020, 0340,017,0374,030, 0340,07,0370,010, 0377,07,0370,016,
1180 	0377,01,0340,03, 077,0,0,0, 077,0,0,0, 077,0,0,0,
1181 	077,0,0,0, 037,0,0,0, 037,0,0,0, 037,0,0,0,
1182 	017,0,0,0, 017,0,0,0, 017,0,0,0, 07,0,0,0,
1183 	07,0200,0,0, 03,0200,0,0, 03,0300,0,0, 01,0340,0,03,
1184 	0,0360,0,03, 0,0170,0,07, 0,074,0,07, 0,037,0,07,
1185 	0,017,0300,07, 0,07,0370,07, 0,01,0377,07, 0,0,0177,0377,
1186 	0,0,017,0377, 0,0,01,0377, 0,0,0,037, 0,0,0,037,
1187 };
1188 static UCHAR1 us_icon132europe[] =
1189 {
1190 	0210,077,0360,07, 0130,077,0360,07, 060,037,0340,07, 0160,037,0340,0377,
1191 	0300,07,0200,0377, 0,0,0,0374, 0,0,0,0374, 0,0,0,0374,
1192 	0,0,0,0374, 0,0,0,0370, 0,0,0,0370, 0,0,0,0370,
1193 	0,0,0,0360, 0,0,0,0360, 0,0,0,0360, 0,0,0,0340,
1194 	0,0,01,0340, 0,0,01,0300, 0,0,03,0300, 0300,0,07,0200,
1195 	0300,0,017,0, 0340,0,036,0, 0340,0,074,0, 0340,0,0370,0,
1196 	0340,03,0360,0, 0340,037,0340,0, 0340,0377,0200,0, 0377,0376,0,0,
1197 	0377,0360,0,0, 0377,0200,0,0, 0370,0,0,0, 0370,0,0,0,
1198 };
1199 
1200 /* Italian version */
1201 static UCHAR1 us_icon130italy[] =
1202 {
1203 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1204 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1205 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1206 	0,0,0,0, 0,0,0,0, 037,0377,0377,0377, 077,0377,0377,0377,
1207 	0177,0377,0377,0377, 0360,0,0,0, 0340,0,0,0, 0340,0,0,0,
1208 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1209 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,017,0,03,
1210 	0340,037,0200,07, 0340,077,0300,017, 0340,0177,0340,037, 0340,0177,0340,037,
1211 };
1212 static UCHAR1 us_icon131italy[] =
1213 {
1214 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1215 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1216 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1217 	0,0,0,0, 0,0,0,0, 0377,0377,0377,0370, 0377,0377,0377,0374,
1218 	0377,0377,0377,0376, 0,0,0,017, 0,0,0,07, 0,0,0,07,
1219 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1220 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0300,0,0360,07,
1221 	0340,01,0370,07, 0360,03,0374,07, 0370,07,0376,07, 0370,07,0376,07,
1222 };
1223 static UCHAR1 us_icon129italy[] =
1224 {
1225 	0340,0177,0340,037, 0340,0177,0340,037, 0340,077,0300,017, 0340,037,0200,07,
1226 	0340,017,0,03, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1227 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1228 	0340,0,0,0, 0340,0,0,0, 0360,0,0,0, 0177,0377,0377,0377,
1229 	077,0377,0377,0377, 037,0377,0377,0377, 0,0,0,0, 0,0,0,0,
1230 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1231 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1232 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1233 };
1234 static UCHAR1 us_icon132italy[] =
1235 {
1236 	0370,07,0376,07, 0370,07,0376,07, 0360,03,0374,07, 0340,01,0370,07,
1237 	0300,0,0360,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1238 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1239 	0,0,0,07, 0,0,0,07, 0,0,0,017, 0377,0377,0377,0376,
1240 	0377,0377,0377,0374, 0377,0377,0377,0370, 0,0,0,0, 0,0,0,0,
1241 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1242 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1243 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1244 };
1245 
1246 /* Indian version */
1247 static UCHAR1 us_icon130india[] =
1248 {
1249 	0,0,0,077, 0,0,03,0377, 0,0,037,0377, 0,0,0377,0340,
1250 	0,03,0376,0, 0,017,0360,0, 0,037,0200,0, 0,076,0,03,
1251 	0,0174,0,017, 0,0370,0,037, 01,0360,0,037, 03,0340,0,077,
1252 	07,0300,0,077, 07,0200,0,077, 017,0,0,077, 016,0,0,037,
1253 	036,0,0,037, 034,0,0,017, 034,0,0,03, 074,0,0,0,
1254 	070,0,0,0, 070,0,0,0, 0170,0,0,0, 0160,0,0,0,
1255 	0160,0,0,0, 0160,0,0,0, 0360,0,0,0, 0340,0,0,0,
1256 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1257 };
1258 static UCHAR1 us_icon131india[] =
1259 {
1260 	0374,0,0,0, 0377,0300,0,0, 0377,0370,0,0, 07,0377,0,0,
1261 	0,0177,0300,0, 0,017,0360,0, 0,01,0370,0, 0300,0,0174,0,
1262 	0360,0,076,0, 0370,0,037,0, 0370,0,017,0200, 0374,0,07,0300,
1263 	0374,0,03,0340, 0374,0,01,0340, 0374,0,0,0360, 0370,0,0,0160,
1264 	0370,0,0,0170, 0360,0,0,070, 0300,0,0,070, 0,0,0,074,
1265 	0,0,0,034, 0,0,0,034, 0,0,0,036, 0,0,0,016,
1266 	0,0,0,016, 0,0,0,016, 0,0,0,017, 0,0,0,07,
1267 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1268 };
1269 static UCHAR1 us_icon129india[] =
1270 {
1271 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1272 	0340,0,0,0, 0360,0,0,0, 0160,0,0,0, 0160,0,0170,0,
1273 	0160,0,0374,0, 0170,01,0376,0, 070,03,0377,0, 070,03,0377,0,
1274 	074,03,0377,0, 034,03,0377,0, 034,01,0376,0, 036,0,0374,0,
1275 	016,0,0170,0, 017,0,0,0, 07,0200,0,0, 07,0300,0,0,
1276 	03,0340,0,0, 01,0360,0,0, 0,0370,0,0, 0,0174,0,0,
1277 	0,076,0,0, 0,037,0200,0, 0,017,0360,0, 0,03,0376,0,
1278 	0,0,0377,0340, 0,0,037,0377, 0,0,03,0377, 0,0,0,077,
1279 };
1280 static UCHAR1 us_icon132india[] =
1281 {
1282 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1283 	0,0,0,07, 0,0,0,017, 0,017,0,016, 0,037,0200,016,
1284 	0,077,0300,016, 0,0177,0340,036, 0,0177,0340,034, 0,0177,0340,034,
1285 	0,0177,0340,074, 0,077,0300,070, 0,037,0200,070, 0,017,0,0170,
1286 	0,0,0,0160, 0,0,0,0360, 0,0,01,0340, 0,0,03,0340,
1287 	0,0,07,0300, 0,0,017,0200, 0,0,037,0, 0,0,076,0,
1288 	0,0,0174,0, 0,01,0370,0, 0,017,0360,0, 0,0177,0300,0,
1289 	07,0377,0,0, 0377,0370,0,0, 0377,0300,0,0, 0374,0,0,0,
1290 };
1291 
1292 /* Israel version */
1293 static UCHAR1 us_icon130israel[] =
1294 {
1295 	0,0,0,077, 0,0,03,0377, 0,0,037,0377, 0,0,0377,0340,
1296 	0,03,0376,0, 0,017,0360,0, 0,037,0200,0, 0,076,0,0,
1297 	0,0174,0,0, 0,0370,0,0, 01,0360,0,0, 03,0340,0,0,
1298 	07,0300,0,0, 07,0200,0,0, 017,0,0,0, 016,0,0,0,
1299 	036,0,0,0, 034,0,036,0, 034,0,077,0, 074,0,077,0200,
1300 	070,0,077,0300, 070,0,077,0340, 0170,0,037,0340, 0160,0,017,0340,
1301 	0160,0,07,0340, 0160,0,03,0300, 0360,0,0,0, 0340,0,0,0,
1302 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1303 };
1304 static UCHAR1 us_icon131israel[] =
1305 {
1306 	0374,0,0,0, 0377,0300,0,0, 0377,0370,0,0, 07,0377,0,0,
1307 	0,0177,0300,0, 0,017,0360,0, 0,01,0370,0, 0,0,0174,0,
1308 	0,0,076,0, 0,0,037,0, 0,0,017,0200, 0,0,07,0300,
1309 	0,0,03,0340, 0,0,01,0340, 0,0,0,0360, 0,0,0,0160,
1310 	0,0,0,0170, 0,0,0,070, 0,0,0,070, 0,0374,0,074,
1311 	01,0376,0,034, 03,0377,0,034, 03,0377,0,036, 03,0377,0,016,
1312 	01,0376,0,016, 0,0374,0,016, 0,0,0,017, 0,0,0,07,
1313 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1314 };
1315 static UCHAR1 us_icon129israel[] =
1316 {
1317 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1318 	0340,0,0,0, 0360,0,03,0200, 0160,0,07,0300, 0160,0,017,0340,
1319 	0160,0,017,0340, 0170,0,017,0340, 070,0,017,0340, 070,0,017,0340,
1320 	074,0,017,0340, 034,0,07,0300, 034,0,03,0200, 036,0,0,0,
1321 	016,0,0,0, 017,0,0,0, 07,0200,0,0, 07,0300,0,0,
1322 	03,0340,0,0, 01,0360,0,0, 0,0370,0,0, 0,0174,0,0,
1323 	0,076,0,0, 0,037,0200,0, 0,017,0360,0, 0,03,0376,0,
1324 	0,0,0377,0340, 0,0,037,0377, 0,0,03,0377, 0,0,0,077,
1325 };
1326 static UCHAR1 us_icon132israel[] =
1327 {
1328 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1329 	0,0,0,07, 0,0,0,017, 0,0,0,016, 0,0,0,016,
1330 	0,0,0,016, 0,0,0,036, 0,0,0,034, 0,0,0,034,
1331 	0,0,0,074, 0,0,0,070, 0,0,0,070, 0,0,0,0170,
1332 	0,0,0,0160, 0,0,0,0360, 0,0,01,0340, 0,0,03,0340,
1333 	0,0,07,0300, 0,0,017,0200, 0,0,037,0, 0,0,076,0,
1334 	0,0,0174,0, 0,01,0370,0, 0,017,0360,0, 0,0177,0300,0,
1335 	07,0377,0,0, 0377,0370,0,0, 0377,0300,0,0, 0374,0,0,0,
1336 };
1337 
1338 /* Danish version */
1339 static UCHAR1 us_icon130denmark[] =
1340 {
1341 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1342 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1343 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0177,0377,0377,0377,
1344 	0377,0377,0377,0377, 0377,0377,0377,0377, 0340,0,0,0, 0340,0,0,0,
1345 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,017,0200,0,
1346 	0340,037,0300,0, 0340,077,0340,0, 0340,0177,0360,0, 0340,0177,0360,0,
1347 	0340,0177,0360,0, 0340,0177,0360,0, 0340,0177,0360,0, 0340,077,0340,0,
1348 	0340,037,0300,0, 0340,017,0200,0, 0340,0,0,0, 0340,0,0,0,
1349 };
1350 static UCHAR1 us_icon131denmark[] =
1351 {
1352 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1353 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1354 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0377,0377,0377,0376,
1355 	0377,0377,0377,0377, 0377,0377,0377,0377, 0,0,0,07, 0,0,0,07,
1356 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,01,0360,07,
1357 	0,03,0370,07, 0,07,0374,07, 0,017,0376,07, 0,017,0376,07,
1358 	0,017,0376,07, 0,017,0376,07, 0,017,0376,07, 0,07,0374,07,
1359 	0,03,0370,07, 0,01,0360,07, 0,0,0,07, 0,0,0,07,
1360 };
1361 static UCHAR1 us_icon129denmark[] =
1362 {
1363 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1364 	0340,0,0,0, 0340,0,0,037, 0340,0,0,077, 0340,0,0,077,
1365 	0340,0,0,077, 0340,0,0,077, 0340,0,0,077, 0340,0,0,077,
1366 	0340,0,0,037, 0340,0,0,037, 0340,0,0,017, 0340,0,0,07,
1367 	0340,0,0,0, 0340,0,0,0, 0377,0377,0377,0377, 0377,0377,0377,0377,
1368 	0177,0377,0377,0377, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1369 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1370 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1371 };
1372 static UCHAR1 us_icon132denmark[] =
1373 {
1374 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1375 	0,0,0,07, 0370,0,0,07, 0374,0,0,07, 0374,0,0,07,
1376 	0374,0,0,07, 0374,0,0,07, 0374,0,0,07, 0374,0,0,07,
1377 	0370,0,0,07, 0370,0,0,07, 0360,0,0,07, 0340,0,0,07,
1378 	0,0,0,07, 0,0,0,07, 0377,0377,0377,0377, 0377,0377,0377,0377,
1379 	0377,0377,0377,0376, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1380 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1381 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1382 };
1383 
1384 /* Japanese version */
1385 static UCHAR1 us_icon130japan[] =
1386 {
1387 	0377,0377,0377,0377, 0377,0377,0377,0377, 0377,0377,0377,0377, 0340,0,0,0,
1388 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1389 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1390 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1391 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1392 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1393 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1394 	0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0, 0340,03,0374,0,
1395 };
1396 static UCHAR1 us_icon131japan[] =
1397 {
1398 	0377,0377,0377,0377, 0377,0377,0377,0377, 0377,0377,0377,0377, 0,0,0,07,
1399 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1400 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1401 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1402 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1403 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1404 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1405 	0,077,0300,07, 0,077,0300,07, 0,077,0300,07, 0,077,0300,07,
1406 };
1407 static UCHAR1 us_icon129japan[] =
1408 {
1409 	0340,03,0374,0, 0340,03,0374,0, 0340,0,0,0, 0340,0,0,0,
1410 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1411 	0340,0,0,03, 0340,0,0,07, 0340,0,0,017, 0340,0,0,037,
1412 	0340,0,0,077, 0340,0,0,077, 0340,0,0,077, 0340,0,0,077,
1413 	0340,0,0,077, 0340,0,0,077, 0340,0,0,077, 0340,0,0,077,
1414 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1415 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1416 	0340,0,0,0, 0377,0377,0377,0377, 0377,0377,0377,0377, 0377,0377,0377,0377,
1417 };
1418 static UCHAR1 us_icon132japan[] =
1419 {
1420 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1421 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1422 	0300,0,0,07, 0340,0,0,07, 0360,0,0,07, 0370,0,0,07,
1423 	0374,0,0,07, 0374,0,0,07, 0374,0,0,07, 0374,0,0,07,
1424 	0374,0,0,07, 0374,0,0,07, 0374,0,0,07, 0374,0,0,07,
1425 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1426 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1427 	0,0,0,07, 0377,0377,0377,0377, 0377,0377,0377,0377, 0377,0377,0377,0377,
1428 };
1429 
1430 /* Swiss version */
1431 static UCHAR1 us_icon130swiss[] =
1432 {
1433 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1434 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1435 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1436 	0,0,0,0, 0,0,0,0, 0,0,0177,0377, 0,0,0377,0377,
1437 	0,01,0377,0377, 0,03,0300,0, 0,07,0200,0, 0,017,0,0,
1438 	0,036,0,0, 0,074,0,0, 0,0170,0,0, 0,0360,0,0,
1439 	01,0340,0,0, 03,0300,0,0, 07,0200,0,0, 017,0,0,0,
1440 	036,01,0340,0, 074,03,0360,0, 0170,07,0370,0, 0370,07,0370,0,
1441 };
1442 static UCHAR1 us_icon131swiss[] =
1443 {
1444 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1445 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1446 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1447 	0,0,0,0, 0,0,0,0, 0377,0376,0,0, 0377,0377,0,0,
1448 	0377,0377,0200,0, 0,03,0300,0, 0,01,0340,0, 0,0,0360,0,
1449 	0,0,0170,0, 0,0,074,0, 0,0,036,0, 0,0,017,0,
1450 	0,0,07,0200, 0,0,03,0300, 0,0,01,0340, 0,0,0,0360,
1451 	0,07,0200,0170, 0,017,0300,074, 0,037,0340,036, 0,037,0340,037,
1452 };
1453 static UCHAR1 us_icon129swiss[] =
1454 {
1455 	0370,07,0370,0, 0170,07,0370,0, 074,03,0360,0, 036,01,0340,0,
1456 	017,0,0,03, 07,0200,0,07, 03,0300,0,017, 01,0340,0,017,
1457 	0,0360,0,017, 0,0170,0,017, 0,074,0,07, 0,036,0,03,
1458 	0,017,0,0, 0,07,0200,0, 0,03,0300,0, 0,01,0377,0377,
1459 	0,0,0377,0377, 0,0,0177,0377, 0,0,0,0, 0,0,0,0,
1460 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1461 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1462 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1463 };
1464 static UCHAR1 us_icon132swiss[] =
1465 {
1466 	0,037,0340,037, 0,037,0340,036, 0,017,0300,074, 0,07,0200,0170,
1467 	0300,0,0,0360, 0340,0,01,0340, 0360,0,03,0300, 0360,0,07,0200,
1468 	0360,0,017,0, 0360,0,036,0, 0340,0,074,0, 0300,0,0170,0,
1469 	0,0,0360,0, 0,01,0340,0, 0,03,0300,0, 0377,0377,0200,0,
1470 	0377,0377,0,0, 0377,0376,0,0, 0,0,0,0, 0,0,0,0,
1471 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1472 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1473 	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
1474 };
1475 
1476 /* UK/Ireland version */
1477 static UCHAR1 us_icon130uk[] =
1478 {
1479 	0,0,0,077, 0,0,03,0377, 0,0,037,0377, 0,0,0377,0340,
1480 	0,03,0376,0, 0,017,0360,0, 0,037,0200,0, 0,076,0,0,
1481 	0,0174,0,0, 0,0370,0,0, 01,0360,0,0, 03,0340,0,0,
1482 	07,0300,0,0, 07,0200,0,0, 017,0,0,0, 016,0,0,0,
1483 	036,0,0,0, 034,0,0,0, 034,0,0,0, 074,03,0377,0,
1484 	070,03,0377,0, 070,03,0377,0, 0170,03,0377,0, 0160,03,0377,0,
1485 	0160,03,0377,0, 0160,0,0,0, 0360,0,0,0, 0340,0,0,0,
1486 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1487 };
1488 static UCHAR1 us_icon131uk[] =
1489 {
1490 	0374,0,0,0, 0377,0300,0,0, 0377,0370,0,0, 07,0377,0,0,
1491 	0,0177,0300,0, 0,017,0360,0, 0,01,0370,0, 0,0,0174,0,
1492 	0,0,076,0, 0,0,037,0, 0,0,017,0200, 0,0,07,0300,
1493 	0,0,03,0340, 0,0,01,0340, 0,0,0,0360, 0,0,0,0160,
1494 	0,0,0,0170, 0,0,0,070, 0,0,0,070, 0,0377,0300,074,
1495 	0,0377,0300,034, 0,0377,0300,034, 0,0377,0300,036, 0,0377,0300,016,
1496 	0,0377,0300,016, 0,0,0,016, 0,0,0,017, 0,0,0,07,
1497 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1498 };
1499 static UCHAR1 us_icon129uk[] =
1500 {
1501 	0340,0,0,0, 0340,0,0,0, 0340,0,0,0, 0340,0,0,0,
1502 	0340,0,0,0, 0360,0,0,0, 0160,0,0,0, 0160,0,0,0,
1503 	0160,0,0,0, 0170,0,0,017, 070,0,0,017, 070,0,0,017,
1504 	074,0,0,017, 034,0,0,017, 034,0,0,017, 036,0,0,017,
1505 	016,0,0,017, 017,0,0,017, 07,0200,0,017, 07,0300,0,017,
1506 	03,0340,0,0, 01,0360,0,0, 0,0370,0,0, 0,0174,0,0,
1507 	0,076,0,0, 0,037,0200,0, 0,017,0360,0, 0,03,0376,0,
1508 	0,0,0377,0340, 0,0,037,0377, 0,0,03,0377, 0,0,0,077,
1509 };
1510 static UCHAR1 us_icon132uk[] =
1511 {
1512 	0,0,0,07, 0,0,0,07, 0,0,0,07, 0,0,0,07,
1513 	0,0,0,07, 0,0,0,017, 0,0,0,016, 0,0,0,016,
1514 	0,0,0,016, 0360,0,0,036, 0360,0,0,034, 0360,0,0,034,
1515 	0360,0,0,074, 0360,0,0,070, 0360,0,0,070, 0360,0,0,0170,
1516 	0360,0,0,0160, 0360,0,0,0360, 0360,0,01,0340, 0360,0,03,0340,
1517 	0,0,07,0300, 0,0,017,0200, 0,0,037,0, 0,0,076,0,
1518 	0,0,0174,0, 0,01,0370,0, 0,017,0360,0, 0,0177,0300,0,
1519 	07,0377,0,0, 0377,0370,0,0, 0377,0300,0,0, 0374,0,0,0,
1520 };
1521 
1522 /* Russian version */
1523 static UCHAR1 us_icon130russia[] =
1524 {
1525 	0,0,0,077, 0,0,03,0377, 0,0,037,0377, 0,0,0377,0340,
1526 	0,03,0376,0, 0,017,0360,0, 0,037,0200,0, 0,076,0,0,
1527 	0,0174,0,0, 0,0370,0,0, 01,0360,0,0, 03,0340,0,0,
1528 	07,0300,0,0, 07,0200,0,0, 017,0,0,0, 016,0,0,0,
1529 	036,0,0,0, 034,0,0,0, 034,0,0,0, 074,0,0,0,
1530 	070,0,0,0, 070,0,0,0, 0170,0,0,0, 0160,0,0,0,
1531 	0160,0,0,0, 0160,0,0,0, 0360,0,0,0, 0340,0,0,0,
1532 	0340,0,0170,0, 0340,0,0374,0, 0340,01,0376,0, 0340,01,0376,0,
1533 };
1534 static UCHAR1 us_icon131russia[] =
1535 {
1536 	0374,0,0,0, 0377,0300,0,0, 0377,0370,0,0, 07,0377,0,0,
1537 	0,0177,0300,0, 0,017,0360,0, 0,01,0370,0, 0,0,0174,0,
1538 	0,0,076,0, 0,0,037,0, 0,0,017,0200, 0,0,07,0300,
1539 	0,0,03,0340, 0,0,01,0340, 0,0,0,0360, 0,0,0,0160,
1540 	0,0,0,0170, 0,0,0,070, 0,0,0,070, 0,0,0,074,
1541 	0,0,0,034, 0,0,0,034, 0,0,0,036, 0,0,0,016,
1542 	0,0,0,016, 0,0,0,016, 0,0,0,017, 0,0,0,07,
1543 	0,036,0,07, 0,077,0,07, 0,0177,0200,07, 0,0177,0200,07,
1544 };
1545 static UCHAR1 us_icon129russia[] =
1546 {
1547 	0340,01,0376,0, 0340,01,0376,0, 0340,0,0374,0, 0340,0,0170,0,
1548 	0340,0,0,0, 0360,0,0,0, 0160,0,0,0, 0160,0,0,0,
1549 	0160,0,0,0, 0170,0,0,0, 070,0,0,0, 070,0,0,0,
1550 	074,0,0,0, 034,0,0,0, 034,0,0,0, 036,0,0,0,
1551 	016,0,0,0, 017,0,0,0, 07,0200,0,0, 07,0300,0,0,
1552 	03,0340,0,0, 01,0360,0,0, 0,0370,0,0, 0,0174,0,0,
1553 	0,076,0,0, 0,037,0200,0, 0,017,0360,0, 0,03,0376,0,
1554 	0,0,0377,0340, 0,0,037,0377, 0,0,03,0377, 0,0,0,077,
1555 };
1556 static UCHAR1 us_icon132russia[] =
1557 {
1558 	0,0177,0200,07, 0,0177,0200,07, 0,077,0,07, 0,036,0,07,
1559 	0,0,0,07, 0,0,0,017, 0,0,0,016, 0,0,0,016,
1560 	0,0,0,016, 0,0,0,036, 0,0,0,034, 0,0,0,034,
1561 	0,0,0,074, 0,0,0,070, 0,0,0,070, 0,0,0,0170,
1562 	0,0,0,0160, 0,0,0,0360, 0,0,01,0340, 0,0,03,0340,
1563 	0,0,07,0300, 0,0,017,0200, 0,0,037,0, 0,0,076,0,
1564 	0,0,0174,0, 0,01,0370,0, 0,017,0360,0, 0,0177,0300,0,
1565 	07,0377,0,0, 0377,0370,0,0, 0377,0300,0,0, 0374,0,0,0,
1566 };
1567 
1568 struct
1569 {
1570 	CHAR *country;
1571 	UCHAR1 *iconul, *iconur, *iconll, *iconlr;
1572 } us_iconlists[] =
1573 {
1574 	{N_("N.America"),   us_icon130namerica,  us_icon129namerica,  us_icon131namerica,  us_icon132namerica},
1575 	{N_("Australia,NZ"),us_icon130ausnz,     us_icon129ausnz,     us_icon131ausnz,     us_icon132ausnz},
1576 	{N_("Denmark"),     us_icon130denmark,   us_icon129denmark,   us_icon131denmark,   us_icon132denmark},
1577 	{N_("Europe"),      us_icon130europe,    us_icon129europe,    us_icon131europe,    us_icon132europe},
1578 	{N_("India"),       us_icon130india,     us_icon129india,     us_icon131india,     us_icon132india},
1579 	{N_("Italy"),       us_icon130italy,     us_icon129italy,     us_icon131italy,     us_icon132italy},
1580 	{N_("Israel"),      us_icon130israel,    us_icon129israel,    us_icon131israel,    us_icon132israel},
1581 	{N_("Japan"),       us_icon130japan,     us_icon129japan,     us_icon131japan,     us_icon132japan},
1582 	{N_("Russia"),      us_icon130russia,    us_icon129russia,    us_icon131russia,    us_icon132russia},
1583 	{N_("Switzerland"), us_icon130swiss,     us_icon129swiss,     us_icon131swiss,     us_icon132swiss},
1584 	{N_("UK,Ireland"),  us_icon130uk,        us_icon129uk,        us_icon131uk,        us_icon132uk},
1585 	{0,0,0,0,0}
1586 };
1587 
1588 /* About Electric */
1589 static DIALOGITEM us_aboutgnudialogitems[] =
1590 {
1591  /*  1 */ {0, {24,320,48,400}, BUTTON, N_("OK")},
1592  /*  2 */ {0, {308,12,324,356}, MESSAGE, N_("Electric comes with ABSOLUTELY NO WARRANTY")},
1593  /*  3 */ {0, {284,12,300,489}, MESSAGE, N_("Copyright (c) 2002 Static Free Software (www.staticfreesoft.com)")},
1594  /*  4 */ {0, {56,8,72,221}, MESSAGE, N_("Written by Steven M. Rubin")},
1595  /*  5 */ {0, {8,8,24,295}, MESSAGE, N_("The Electric(tm) Design System")},
1596  /*  6 */ {0, {32,8,48,246}, MESSAGE, N_("Version XXXX")},
1597  /*  7 */ {0, {4,420,36,452}, ICON|INACTIVE, (CHAR *)us_icon130namerica},
1598  /*  8 */ {0, {36,420,68,452}, ICON|INACTIVE, (CHAR *)us_icon129namerica},
1599  /*  9 */ {0, {4,452,36,484}, ICON|INACTIVE, (CHAR *)us_icon131namerica},
1600  /* 10 */ {0, {36,452,68,484}, ICON|INACTIVE, (CHAR *)us_icon132namerica},
1601  /* 11 */ {0, {100,8,273,487}, SCROLL, x_("")},
1602  /* 12 */ {0, {76,160,94,348}, BUTTON, N_("And a Cast of Thousands")},
1603  /* 13 */ {0, {332,12,348,330}, MESSAGE, N_("This is free software, and you are welcome to")},
1604  /* 14 */ {0, {308,358,326,487}, BUTTON, N_("Warranty details")},
1605  /* 15 */ {0, {344,358,362,487}, BUTTON, N_("Copying details")},
1606  /* 16 */ {0, {352,12,368,309}, MESSAGE, N_("redistribute it under certain conditions")},
1607  /* 17 */ {0, {76,388,92,484}, POPUP, x_("")}
1608 };
1609 static DIALOG us_aboutgnudialog = {{50,75,427,573}, 0, 0, 17, us_aboutgnudialogitems, 0, 0};
1610 
1611 /* special items for the "About Electric" dialog: */
1612 #define DABO_COPYRIGHT    3			/* copyright information (message) */
1613 #define DABO_VERSION      6			/* version number (message) */
1614 #define DABO_ICONUL       7			/* upper-left part of icon (icon) */
1615 #define DABO_ICONUR       8			/* upper-right part of icon (icon) */
1616 #define DABO_ICONLL       9			/* lower-left part of icon (icon) */
1617 #define DABO_ICONLR       10		/* lower-right part of icon (icon) */
1618 #define DABO_INFORMATION  11		/* information area (scroll) */
1619 #define DABO_AUTHORS      12		/* authors (button) */
1620 #define DABO_WARRANTY     14		/* warranty (button) */
1621 #define DABO_COPYING      15		/* copying (button) */
1622 #define DABO_PLUGTYPE     17		/* type of plug (popup) */
1623 
us_aboutdlog(void)1624 INTBIG us_aboutdlog(void)
1625 {
1626 	CHAR line[256], date[30], *language, *truename, *newlang[50];
1627 	INTBIG itemHit, i, pluglocale;
1628 	BOOLEAN castlisted;
1629 	FILE *io;
1630 	REGISTER void *infstr, *dia;
1631 
1632 	/* show the "about" dialog */
1633 #ifdef EPROGRAMNAME
1634 	esnprintf(line, 256, _("About %s"), EPROGRAMNAME);
1635 	us_aboutgnudialog.movable = line;
1636 #else
1637 	us_aboutgnudialog.movable = _("About Electric");
1638 #endif
1639 	dia = DiaInitDialog(&us_aboutgnudialog);
1640 	if (dia == 0) return(0);
1641 	DiaInitTextDialog(dia, DABO_INFORMATION, DiaNullDlogList, DiaNullDlogItem,
1642 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT|SCSMALLFONT|SCHORIZBAR);
1643 	for(i=0; us_iconlists[i].country != 0; i++) newlang[i] = TRANSLATE(us_iconlists[i].country);
1644 	DiaSetPopup(dia, DABO_PLUGTYPE, i, newlang);
1645 	pluglocale = 0;
1646 
1647 	/* show the version and copyright information */
1648 	(void)estrcpy(line, _("Version "));
1649 	(void)estrcat(line, el_version);
1650 	(void)estrcat(line, x_(", "));
1651 	(void)estrcat(line, WIDENSTRINGDEFINE(__DATE__));
1652 	DiaSetText(dia, DABO_VERSION, line);
1653 	estrcpy(date, timetostring(getcurrenttime()));
1654 	date[24] = 0;
1655 	(void)esnprintf(line, 256,
1656 		_("Copyright (c) %s Static Free Software (www.staticfreesoft.com)"), &date[20]);
1657 	DiaSetText(dia, DABO_COPYRIGHT, line);
1658 
1659 	castlisted = FALSE;
1660 	for(;;)
1661 	{
1662 		itemHit = DiaNextHit(dia);
1663 		if (itemHit == OK) break;
1664 		if (itemHit == DABO_INFORMATION)
1665 		{
1666 			if (!castlisted) continue;
1667 			i = DiaGetCurLine(dia, DABO_INFORMATION);
1668 			if (i < 0) continue;
1669 			infstr = initinfstr();
1670 			formatinfstr(infstr, x_("%s: %s"), us_castofthousands[i].name,
1671 				TRANSLATE(us_castofthousands[i].help));
1672 			DiaSetScrollLine(dia, DABO_INFORMATION, i, returninfstr(infstr));
1673 			continue;
1674 		}
1675 		if (itemHit == DABO_AUTHORS)
1676 		{
1677 			DiaLoadTextDialog(dia, DABO_INFORMATION, DiaNullDlogList,
1678 				DiaNullDlogItem, DiaNullDlogDone, -1);
1679 			for(i=0; us_castofthousands[i].name != 0; i++)
1680 				DiaStuffLine(dia, DABO_INFORMATION, us_castofthousands[i].name);
1681 			DiaSelectLine(dia, DABO_INFORMATION, -1);
1682 			castlisted = TRUE;
1683 			continue;
1684 		}
1685 		if (itemHit == DABO_WARRANTY)
1686 		{
1687 			DiaLoadTextDialog(dia, DABO_INFORMATION, DiaNullDlogList,
1688 				DiaNullDlogItem, DiaNullDlogDone, -1);
1689 			language = elanguage();
1690 			if (namesame(language, x_("en")) != 0)
1691 			{
1692 				infstr = initinfstr();
1693 				formatinfstr(infstr, x_("%sinternational%s%s%sLC_MESSAGES%slicense.txt"),
1694 					el_libdir, DIRSEPSTR, language, DIRSEPSTR, DIRSEPSTR);
1695 				io = xopen(returninfstr(infstr), el_filetypetext, 0, &truename);
1696 				if (io == 0) language = x_("en"); else
1697 				{
1698 					if (us_showforeignlicense(io, 4, DABO_INFORMATION, dia))
1699 						language = x_("en");
1700 					xclose(io);
1701 				}
1702 			}
1703 			if (namesame(language, x_("en")) == 0)
1704 			{
1705 				for(i=0; us_gnuwarranty[i] != 0; i++)
1706 					DiaStuffLine(dia, DABO_INFORMATION, us_gnuwarranty[i]);
1707 			}
1708 			DiaSelectLine(dia, DABO_INFORMATION, -1);
1709 			castlisted = FALSE;
1710 			continue;
1711 		}
1712 		if (itemHit == DABO_COPYING)
1713 		{
1714 			DiaLoadTextDialog(dia, DABO_INFORMATION, DiaNullDlogList,
1715 				DiaNullDlogItem, DiaNullDlogDone, -1);
1716 			language = elanguage();
1717 			if (namesame(language, x_("en")) != 0)
1718 			{
1719 				infstr = initinfstr();
1720 				formatinfstr(infstr, x_("%sinternational%s%s%sLC_MESSAGES%slicense.txt"),
1721 					el_libdir, DIRSEPSTR, language, DIRSEPSTR, DIRSEPSTR);
1722 				io = xopen(returninfstr(infstr), el_filetypetext, 0, &truename);
1723 				if (io == 0) language = x_("en"); else
1724 				{
1725 					if (us_showforeignlicense(io, 3, DABO_INFORMATION, dia))
1726 						language = x_("en");
1727 					xclose(io);
1728 				}
1729 			}
1730 			if (namesame(language, x_("en")) == 0)
1731 			{
1732 				for(i=0; us_gnucopying[i] != 0; i++)
1733 					DiaStuffLine(dia, DABO_INFORMATION, us_gnucopying[i]);
1734 			}
1735 			DiaSelectLine(dia, DABO_INFORMATION, -1);
1736 			castlisted = FALSE;
1737 			continue;
1738 		}
1739 		if (itemHit == DABO_PLUGTYPE)
1740 		{
1741 			i = DiaGetPopupEntry(dia, DABO_PLUGTYPE);
1742 			if (i == pluglocale) continue;
1743 			pluglocale =  i;
1744 			DiaChangeIcon(dia, DABO_ICONUL, us_iconlists[pluglocale].iconul);
1745 			DiaChangeIcon(dia, DABO_ICONUR, us_iconlists[pluglocale].iconur);
1746 			DiaChangeIcon(dia, DABO_ICONLL, us_iconlists[pluglocale].iconll);
1747 			DiaChangeIcon(dia, DABO_ICONLR, us_iconlists[pluglocale].iconlr);
1748 			continue;
1749 		}
1750 	}
1751 	DiaDoneDialog(dia);
1752 	return(0);
1753 }
1754 
us_showforeignlicense(FILE * io,INTBIG section,INTBIG item,void * dia)1755 BOOLEAN us_showforeignlicense(FILE *io, INTBIG section, INTBIG item, void *dia)
1756 {
1757 	REGISTER INTBIG foundsection;
1758 	REGISTER BOOLEAN foundtext;
1759 	CHAR line[200];
1760 
1761 	foundsection = 0;
1762 	foundtext = FALSE;
1763 	for(;;)
1764 	{
1765 		if (xfgets(line, 200, io)) break;
1766 		if (line[0] == '*' && line[1] == '*')
1767 		{
1768 			foundsection++;
1769 			if (foundsection > section) break;
1770 			continue;
1771 		}
1772 		if (foundsection == section)
1773 		{
1774 			DiaStuffLine(dia, item, line);
1775 			foundtext = TRUE;
1776 		}
1777 	}
1778 	if (foundtext) return(FALSE);
1779 	return(TRUE);
1780 }
1781 
1782 /****************************** ALIGNMENT OPTIONS DIALOG ******************************/
1783 
1784 /* Alignment Options */
1785 static DIALOGITEM us_alignmentdialogitems[] =
1786 {
1787 /*  1 */ {0, {68,340,92,404}, BUTTON, N_("OK")},
1788 /*  2 */ {0, {68,32,92,96}, BUTTON, N_("Cancel")},
1789 /*  3 */ {0, {8,8,24,205}, MESSAGE, N_("Alignment of cursor to grid:")},
1790 /*  4 */ {0, {40,8,56,205}, MESSAGE, N_("Alignment of edges to grid:")},
1791 /*  5 */ {0, {8,208,24,280}, EDITTEXT, x_("")},
1792 /*  6 */ {0, {40,208,56,280}, EDITTEXT, x_("")},
1793 /*  7 */ {0, {16,284,32,426}, MESSAGE, N_("Values of zero will")},
1794 /*  8 */ {0, {32,284,48,428}, MESSAGE, N_("cause no alignment.")}
1795 };
1796 static DIALOG us_alignmentdialog = {{50,75,154,512}, N_("Alignment Options"), 0, 8, us_alignmentdialogitems, 0, 0};
1797 
1798 /* special items for the "alignment options" dialog: */
1799 #define DALI_GRID   5		/* grid alignment (edit text) */
1800 #define DALI_EDGE   6		/* edge alignment (edit text) */
1801 
us_alignmentdlog(void)1802 INTBIG us_alignmentdlog(void)
1803 {
1804 	INTBIG itemHit, retval;
1805 	REGISTER void *dia;
1806 
1807 	if (us_needwindow()) return(0);
1808 
1809 	/* display the alignment settings dialog box */
1810 	dia = DiaInitDialog(&us_alignmentdialog);
1811 	if (dia == 0) return(0);
1812 	DiaSetText(dia, DALI_GRID, frtoa(us_alignment_ratio));
1813 	DiaSetText(dia, DALI_EDGE, frtoa(us_edgealignment_ratio));
1814 
1815 	/* loop until done */
1816 	for(;;)
1817 	{
1818 		itemHit = DiaNextHit(dia);
1819 		if (itemHit == OK || itemHit == CANCEL) break;
1820 	}
1821 
1822 	if (itemHit != CANCEL)
1823 	{
1824 		/* see if alignment changed */
1825 		retval = atofr(DiaGetText(dia, DALI_GRID));
1826 		if (retval != us_alignment_ratio)
1827 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_alignment_ratio_key, retval, VINTEGER);
1828 		retval = atofr(DiaGetText(dia, DALI_EDGE));
1829 		if (retval != us_edgealignment_ratio)
1830 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_alignment_edge_ratio_key, retval, VINTEGER);
1831 	}
1832 	DiaDoneDialog(dia);
1833 	return(0);
1834 }
1835 
1836 /****************************** ARC CREATION OPTIONS DIALOG ******************************/
1837 
1838 /* New arc options */
1839 static DIALOGITEM us_defarcdialogitems[] =
1840 {
1841  /*  1 */ {0, {184,304,208,376}, BUTTON, N_("OK")},
1842  /*  2 */ {0, {184,64,208,136}, BUTTON, N_("Cancel")},
1843  /*  3 */ {0, {4,140,20,420}, POPUP, x_("")},
1844  /*  4 */ {0, {4,4,20,136}, RADIO, N_("Defaults for arc:")},
1845  /*  5 */ {0, {32,4,48,164}, RADIO, N_("Defaults for all arcs")},
1846  /*  6 */ {0, {152,360,168,412}, BUTTON, N_("Set pin")},
1847  /*  7 */ {0, {72,8,88,64}, CHECK, N_("Rigid")},
1848  /*  8 */ {0, {72,104,88,204}, CHECK, N_("Fixed-angle")},
1849  /*  9 */ {0, {72,216,88,288}, CHECK, N_("Slidable")},
1850  /* 10 */ {0, {96,8,112,84}, CHECK, N_("Negated")},
1851  /* 11 */ {0, {96,104,112,196}, CHECK, N_("Directional")},
1852  /* 12 */ {0, {96,216,112,336}, CHECK, N_("Ends extended")},
1853  /* 13 */ {0, {32,228,52,420}, BUTTON, N_("Reset to initial defaults")},
1854  /* 14 */ {0, {128,64,144,152}, EDITTEXT, x_("")},
1855  /* 15 */ {0, {128,8,144,56}, MESSAGE, N_("Width:")},
1856  /* 16 */ {0, {128,176,144,224}, MESSAGE, N_("Angle:")},
1857  /* 17 */ {0, {128,232,144,296}, EDITTEXT, x_("")},
1858  /* 18 */ {0, {152,8,168,39}, MESSAGE, N_("Pin:")},
1859  /* 19 */ {0, {152,40,168,348}, MESSAGE, x_("")}
1860 };
1861 static DIALOG us_defarcdialog = {{50,75,267,505}, N_("New Arc Options"), 0, 19, us_defarcdialogitems, 0, 0};
1862 
1863 static ARCPROTO *us_thisap;
1864 static NODEPROTO *us_posprims;
1865 
1866 static void us_defarcload(ARCPROTO*, NODEPROTO**, INTBIG, void*);
1867 static BOOLEAN us_topofpins(CHAR**);
1868 static CHAR *us_nextpins(void);
1869 
1870 /* special items for the "defarc" dialog: */
1871 #define DNAO_SPECARC     3		/* specific arc (popup) */
1872 #define DNAO_SPECDEF     4		/* defaults for specific type (radio) */
1873 #define DNAO_ALLDEF      5		/* defaults for all types (radio) */
1874 #define DNAO_SETPIN      6		/* set pin (button) */
1875 #define DNAO_RIGID       7		/* rigid (check) */
1876 #define DNAO_FIXANGLE    8		/* fixed-angle (check) */
1877 #define DNAO_SLIDABLE    9		/* slidable (check) */
1878 #define DNAO_NEGATED     10		/* negated (check) */
1879 #define DNAO_DIRECTIONAL 11		/* directional (check) */
1880 #define DNAO_ENDSEXTEND  12		/* ends extended (check) */
1881 #define DNAO_RESETSTATE  13		/* reset to initial state (button) */
1882 #define DNAO_WIDTH       14		/* width (edit text) */
1883 #define DNAO_WIDTH_T     15		/* width title (message) */
1884 #define DNAO_ANGLE_T     16		/* angle title (message) */
1885 #define DNAO_ANGLE       17		/* angle (edit text) */
1886 #define DNAO_DEFPIN_T    18		/* default pin title (message) */
1887 #define DNAO_DEFPIN      19		/* default pin (message) */
1888 
1889 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
1890 extern "C" {
1891 #endif
1892 	extern DIALOG us_listdialog;
1893 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
1894 }
1895 #endif
1896 
us_defarcdlog(void)1897 INTBIG us_defarcdlog(void)
1898 {
1899 	INTBIG itemHit;
1900 	REGISTER INTBIG allstyle, i, j, origallstyle, bits, wid;
1901 	REGISTER VARIABLE *var;
1902 	CHAR **arcnames;
1903 	REGISTER ARCPROTO *ap, **arcs;
1904 	REGISTER NODEPROTO **pins, *np;
1905 	REGISTER void *dia, *subdia;
1906 
1907 	/* display the default arc dialog box */
1908 	dia = DiaInitDialog(&us_defarcdialog);
1909 	if (dia == 0) return(0);
1910 
1911 	/* remember all state */
1912 	var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_arcstylekey);
1913 	if (var != NOVARIABLE) allstyle = var->addr; else
1914 		allstyle = WANTFIXANG;
1915 	origallstyle = allstyle;
1916 	for(i=0, ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto) i++;
1917 	pins = (NODEPROTO **)emalloc(i * (sizeof (NODEPROTO *)), el_tempcluster);
1918 	arcs = (ARCPROTO **)emalloc(i * (sizeof (ARCPROTO *)), el_tempcluster);
1919 	arcnames = (CHAR **)emalloc(i * (sizeof (CHAR *)), el_tempcluster);
1920 	if (pins == 0 || arcs == 0 || arcnames == 0) return(0);
1921 	j = 0;
1922 	for(i=0, ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto, i++)
1923 	{
1924 		var = getvalkey((INTBIG)ap, VARCPROTO, VINTEGER, us_arcstylekey);
1925 		if (var != NOVARIABLE) ap->temp1 = var->addr; else
1926 			ap->temp1 = ap->userbits;
1927 		ap->temp2 = defaultarcwidth(ap);
1928 		pins[i] = getpinproto(ap);
1929 		arcs[i] = ap;
1930 		arcnames[i] = ap->protoname;
1931 		if (ap == us_curarcproto) j = i;
1932 	}
1933 
1934 	/* initially load for first arc in technology */
1935 	us_thisap = us_curarcproto;
1936 	us_defarcload(us_thisap, pins, allstyle, dia);
1937 	DiaSetControl(dia, DNAO_SPECDEF, 1);
1938 	DiaSetPopup(dia, DNAO_SPECARC, i, arcnames);
1939 	DiaSetPopupEntry(dia, DNAO_SPECARC, j);
1940 	efree((CHAR *)arcnames);
1941 
1942 	/* loop until done */
1943 	for(;;)
1944 	{
1945 		itemHit = DiaNextHit(dia);
1946 		if (itemHit == OK || itemHit == CANCEL) break;
1947 		if (itemHit == DNAO_RIGID || itemHit == DNAO_FIXANGLE ||
1948 			itemHit == DNAO_SLIDABLE || itemHit == DNAO_NEGATED ||
1949 			itemHit == DNAO_DIRECTIONAL || itemHit == DNAO_ENDSEXTEND)
1950 		{
1951 			j = DiaGetControl(dia, itemHit);
1952 			DiaSetControl(dia, itemHit, 1-j);
1953 			if (DiaGetControl(dia, DNAO_SPECDEF) == 0) i = allstyle; else
1954 				i = us_thisap->temp1;
1955 			switch (itemHit)
1956 			{
1957 				case DNAO_RIGID:
1958 					if (j == 0) i |= WANTFIX; else
1959 						i &= ~WANTFIX;
1960 					break;
1961 				case DNAO_FIXANGLE:
1962 					if (j == 0) i |= WANTFIXANG; else
1963 						i &= ~WANTFIXANG;
1964 					break;
1965 				case DNAO_SLIDABLE:
1966 					if (j != 0) i |= WANTCANTSLIDE; else
1967 						i &= ~WANTCANTSLIDE;
1968 					break;
1969 				case DNAO_NEGATED:
1970 					if (j == 0) i |= WANTNEGATED; else
1971 						i &= ~WANTNEGATED;
1972 					break;
1973 				case DNAO_DIRECTIONAL:
1974 					if (j == 0) i |= WANTDIRECTIONAL; else
1975 						i &= ~WANTDIRECTIONAL;
1976 					break;
1977 				case DNAO_ENDSEXTEND:
1978 					if (j != 0) i |= WANTNOEXTEND; else
1979 						i &= ~WANTNOEXTEND;
1980 					break;
1981 			}
1982 			if (DiaGetControl(dia, DNAO_SPECDEF) == 0) allstyle = i; else
1983 				us_thisap->temp1 = i;
1984 			continue;
1985 		}
1986 		if (itemHit == DNAO_SPECDEF)
1987 		{
1988 			us_defarcload(us_thisap, pins, allstyle, dia);
1989 			DiaSetControl(dia, DNAO_SPECDEF, 1);
1990 			DiaSetControl(dia, DNAO_ALLDEF, 0);
1991 			continue;
1992 		}
1993 		if (itemHit == DNAO_ALLDEF)
1994 		{
1995 			us_defarcload(NOARCPROTO, pins, allstyle, dia);
1996 			DiaSetControl(dia, DNAO_SPECDEF, 0);
1997 			DiaSetControl(dia, DNAO_ALLDEF, 1);
1998 			continue;
1999 		}
2000 		if (itemHit == DNAO_RESETSTATE)
2001 		{
2002 			allstyle = WANTFIXANG;
2003 			DiaSetControl(dia, DNAO_RIGID, 0);
2004 			DiaSetControl(dia, DNAO_FIXANGLE, 1);
2005 			DiaSetControl(dia, DNAO_SLIDABLE, 1);
2006 			DiaSetControl(dia, DNAO_NEGATED, 0);
2007 			DiaSetControl(dia, DNAO_DIRECTIONAL, 0);
2008 			DiaSetControl(dia, DNAO_ENDSEXTEND, 1);
2009 			continue;
2010 		}
2011 		if (itemHit == DNAO_SPECARC)
2012 		{
2013 			i = DiaGetPopupEntry(dia, DNAO_SPECARC);
2014 			us_thisap = arcs[i];
2015 			us_defarcload(us_thisap, pins, allstyle, dia);
2016 			continue;
2017 		}
2018 		if (itemHit == DNAO_WIDTH)
2019 		{
2020 			if (DiaGetControl(dia, DNAO_SPECDEF) == 0) continue;
2021 			us_thisap->temp2 = atola(DiaGetText(dia, DNAO_WIDTH), 0);
2022 			continue;
2023 		}
2024 		if (itemHit == DNAO_ANGLE)
2025 		{
2026 			if (DiaGetControl(dia, DNAO_SPECDEF) == 0) continue;
2027 			us_thisap->temp1 = (us_thisap->temp1 & ~AANGLEINC) |
2028 				((eatoi(DiaGetText(dia, DNAO_ANGLE))%360) << AANGLEINCSH);
2029 			continue;
2030 		}
2031 		if (itemHit == DNAO_SETPIN)
2032 		{
2033 			if (DiaGetControl(dia, DNAO_SPECDEF) == 0) continue;
2034 			subdia = DiaInitDialog(&us_listdialog);
2035 			if (subdia == 0) return(0);
2036 			DiaInitTextDialog(subdia, 3, us_topofpins, us_nextpins, DiaNullDlogDone,
2037 				0, SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT);
2038 			DiaSetText(subdia, 4, _("Select a node to use as a pin"));
2039 
2040 			for(;;)
2041 			{
2042 				itemHit = DiaNextHit(subdia);
2043 				if (itemHit == OK || itemHit == CANCEL) break;
2044 			}
2045 			np = getnodeproto(DiaGetScrollLine(subdia, 3, DiaGetCurLine(subdia, DNAO_SPECARC)));
2046 			DiaDoneDialog(subdia);
2047 			if (itemHit == CANCEL) continue;
2048 
2049 			for(i=0, ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto, i++)
2050 				if (us_thisap == ap) break;
2051 			if (ap != NOARCPROTO) pins[i] = np;
2052 			DiaSetText(dia, DNAO_DEFPIN, describenodeproto(np));
2053 			continue;
2054 		}
2055 	}
2056 
2057 	if (itemHit != CANCEL)
2058 	{
2059 		for(i=0, ap = el_curtech->firstarcproto; ap != NOARCPROTO;
2060 			ap = ap->nextarcproto, i++)
2061 		{
2062 			var = getvalkey((INTBIG)ap, VARCPROTO, VINTEGER, us_arcstylekey);
2063 			if (var != NOVARIABLE) bits = var->addr; else
2064 				bits = ap->userbits;
2065 			if (ap->temp1 != bits)
2066 			{
2067 				if ((ap->temp1 & AANGLEINC) != (bits & AANGLEINC))
2068 					(void)setval((INTBIG)ap, VARCPROTO, x_("userbits"), ap->temp1, VINTEGER);
2069 				if ((ap->temp1 & ~AANGLEINC) != (bits & ~AANGLEINC))
2070 					(void)setvalkey((INTBIG)ap, VARCPROTO, us_arcstylekey, ap->temp1, VINTEGER);
2071 			}
2072 			if (ap->temp2 != defaultarcwidth(ap))
2073 			{
2074 				wid = (arcprotowidthoffset(ap) + ap->temp2) * WHOLE /
2075 					el_curlib->lambda[ap->tech->techindex];
2076 				(void)setvalkey((INTBIG)ap, VARCPROTO, el_arc_width_default_key,
2077 					wid, VINTEGER);
2078 			}
2079 			np = getpinproto(ap);
2080 			if (np != pins[i])
2081 				(void)setval((INTBIG)ap, VARCPROTO, x_("ARC_Default_Pin"), (INTBIG)pins[i], VNODEPROTO);
2082 		}
2083 		if (allstyle != origallstyle)
2084 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_arcstylekey, allstyle, VINTEGER);
2085 	}
2086 	DiaDoneDialog(dia);
2087 	efree((CHAR *)pins);
2088 	efree((CHAR *)arcs);
2089 	return(0);
2090 }
2091 
us_topofpins(CHAR ** c)2092 BOOLEAN us_topofpins(CHAR **c)
2093 {
2094 	Q_UNUSED( c );
2095 	us_posprims = el_curtech->firstnodeproto;
2096 	return(TRUE);
2097 }
2098 
us_nextpins(void)2099 CHAR *us_nextpins(void)
2100 {
2101 	REGISTER CHAR *nextname;
2102 	REGISTER INTBIG i;
2103 	REGISTER PORTPROTO *pp;
2104 
2105 	for( ; us_posprims != NONODEPROTO; us_posprims = us_posprims->nextnodeproto)
2106 	{
2107 		/* test this pin for validity */
2108 		pp = us_posprims->firstportproto;
2109 		for(i=0; pp->connects[i] != NOARCPROTO; i++)
2110 			if (pp->connects[i] == us_thisap) break;
2111 		if (pp->connects[i] == NOARCPROTO) continue;
2112 		nextname = us_posprims->protoname;
2113 		us_posprims = us_posprims->nextnodeproto;
2114 		return(nextname);
2115 	}
2116 	return(0);
2117 }
2118 
2119 /*
2120  * Helper routine for arc options
2121  */
us_defarcload(ARCPROTO * ap,NODEPROTO ** pins,INTBIG allstyle,void * dia)2122 void us_defarcload(ARCPROTO *ap, NODEPROTO **pins, INTBIG allstyle, void *dia)
2123 {
2124 	REGISTER NODEPROTO *np;
2125 	REGISTER ARCPROTO *oap;
2126 	REGISTER INTBIG i;
2127 	REGISTER INTBIG style;
2128 	CHAR line[20];
2129 
2130 	if (ap == NOARCPROTO)
2131 	{
2132 		style = allstyle;
2133 		DiaDimItem(dia, DNAO_SPECARC);
2134 		DiaUnDimItem(dia, DNAO_RESETSTATE);
2135 		DiaDimItem(dia, DNAO_WIDTH_T);
2136 		DiaSetText(dia, DNAO_WIDTH, x_(""));
2137 		DiaNoEditControl(dia, DNAO_WIDTH);
2138 		DiaDimItem(dia, DNAO_ANGLE_T);
2139 		DiaSetText(dia, DNAO_ANGLE, x_(""));
2140 		DiaNoEditControl(dia, DNAO_ANGLE);
2141 		DiaDimItem(dia, DNAO_DEFPIN_T);
2142 		DiaSetText(dia, DNAO_DEFPIN, x_(""));
2143 		DiaDimItem(dia, DNAO_SETPIN);
2144 	} else
2145 	{
2146 		style = ap->temp1;
2147 		DiaUnDimItem(dia, DNAO_SPECARC);
2148 		DiaDimItem(dia, DNAO_RESETSTATE);
2149 		DiaUnDimItem(dia, DNAO_WIDTH_T);
2150 		DiaSetText(dia, -DNAO_WIDTH, latoa(ap->temp2 - arcprotowidthoffset(ap), 0));
2151 		DiaEditControl(dia, DNAO_WIDTH);
2152 		DiaUnDimItem(dia, DNAO_ANGLE_T);
2153 		(void)esnprintf(line, 20, x_("%ld"), (ap->userbits&AANGLEINC) >> AANGLEINCSH);
2154 		DiaSetText(dia, DNAO_ANGLE, line);
2155 		DiaEditControl(dia, DNAO_ANGLE);
2156 		DiaUnDimItem(dia, DNAO_DEFPIN_T);
2157 		np = NONODEPROTO;
2158 		for(i=0, oap = el_curtech->firstarcproto; oap != NOARCPROTO; oap = oap->nextarcproto, i++)
2159 			if (ap == oap) np = pins[i];
2160 		DiaSetText(dia, DNAO_DEFPIN, describenodeproto(np));
2161 		DiaUnDimItem(dia, DNAO_SETPIN);
2162 	}
2163 	DiaSetControl(dia, DNAO_RIGID, (style&WANTFIX) != 0 ? 1 : 0);
2164 	DiaSetControl(dia, DNAO_FIXANGLE, (style&WANTFIXANG) != 0 ? 1 : 0);
2165 	DiaSetControl(dia, DNAO_SLIDABLE, (style&WANTCANTSLIDE) == 0 ? 1 : 0);
2166 	DiaSetControl(dia, DNAO_NEGATED, (style&WANTNEGATED) != 0 ? 1 : 0);
2167 	DiaSetControl(dia, DNAO_DIRECTIONAL, (style&WANTDIRECTIONAL) != 0 ? 1 : 0);
2168 	DiaSetControl(dia, DNAO_ENDSEXTEND, (style&WANTNOEXTEND) == 0 ? 1 : 0);
2169 }
2170 
2171 /****************************** ARC SIZE DIALOG ******************************/
2172 
2173 /* Arc Size */
2174 static DIALOGITEM us_arcsizedialogitems[] =
2175 {
2176 /*  1 */ {0, {36,96,60,176}, BUTTON, N_("OK")},
2177 /*  2 */ {0, {36,4,60,84}, BUTTON, N_("Cancel")},
2178 /*  3 */ {0, {8,4,24,84}, MESSAGE|INACTIVE, N_("Width")},
2179 /*  4 */ {0, {8,92,24,172}, EDITTEXT, x_("")}
2180 };
2181 static DIALOG us_arcsizedialog = {{75,75,144,260}, N_("Set Arc Size"), 0, 4, us_arcsizedialogitems, 0, 0};
2182 
2183 /* special items for the "arc size" dialog: */
2184 #define DARS_WIDTH   4		/* arc width (edit text) */
2185 
us_arcsizedlog(CHAR * paramstart[])2186 INTBIG us_arcsizedlog(CHAR *paramstart[])
2187 {
2188 	INTBIG itemHit;
2189 	INTBIG ret;
2190 	static CHAR w[20];
2191 	REGISTER void *dia;
2192 
2193 	/* display the arc size dialog box */
2194 	dia = DiaInitDialog(&us_arcsizedialog);
2195 	if (dia == 0) return(0);
2196 
2197 	/* loop until done */
2198 	for(;;)
2199 	{
2200 		itemHit = DiaNextHit(dia);
2201 		if (itemHit == OK || itemHit == CANCEL) break;
2202 	}
2203 
2204 	ret = 0;
2205 	if (itemHit != CANCEL)
2206 	{
2207 		estrcpy(w, DiaGetText(dia, DARS_WIDTH));
2208 		paramstart[0] = w;
2209 		ret = 1;
2210 	}
2211 	DiaDoneDialog(dia);
2212 	return(ret);
2213 }
2214 
2215 /****************************** ARRAY DIALOG ******************************/
2216 
2217 /* Array */
2218 static DIALOGITEM us_arraydialogitems[] =
2219 {
2220  /*  1 */ {0, {264,412,288,476}, BUTTON, N_("OK")},
2221  /*  2 */ {0, {264,316,288,380}, BUTTON, N_("Cancel")},
2222  /*  3 */ {0, {28,160,44,205}, EDITTEXT, x_("1")},
2223  /*  4 */ {0, {108,160,124,205}, EDITTEXT, x_("1")},
2224  /*  5 */ {0, {180,160,196,235}, EDITTEXT, x_("0")},
2225  /*  6 */ {0, {208,160,224,235}, EDITTEXT, x_("0")},
2226  /*  7 */ {0, {268,4,284,182}, CHECK, N_("Generate array indices")},
2227  /*  8 */ {0, {4,216,20,393}, CHECK, N_("Flip alternate columns")},
2228  /*  9 */ {0, {84,216,100,376}, CHECK, N_("Flip alternate rows")},
2229  /* 10 */ {0, {28,36,44,151}, MESSAGE, N_("X repeat factor:")},
2230  /* 11 */ {0, {108,36,124,151}, MESSAGE, N_("Y repeat factor:")},
2231  /* 12 */ {0, {180,4,196,154}, MESSAGE, N_("X edge overlap:")},
2232  /* 13 */ {0, {208,4,224,154}, MESSAGE, N_("Y centerline distance:")},
2233  /* 14 */ {0, {160,244,176,480}, RADIO, N_("Space by edge overlap")},
2234  /* 15 */ {0, {184,244,200,480}, RADIO, N_("Space by centerline distance")},
2235  /* 16 */ {0, {28,216,44,425}, CHECK, N_("Stagger alternate columns")},
2236  /* 17 */ {0, {108,216,124,400}, CHECK, N_("Stagger alternate rows")},
2237  /* 18 */ {0, {208,244,224,480}, RADIO, N_("Space by characteristic spacing")},
2238  /* 19 */ {0, {232,244,248,480}, RADIO, N_("Space by last measured distance")},
2239  /* 20 */ {0, {244,4,260,182}, CHECK, N_("Linear diagonal array")},
2240  /* 21 */ {0, {52,216,68,425}, CHECK, N_("Center about original")},
2241  /* 22 */ {0, {132,216,148,425}, CHECK, N_("Center about original")},
2242  /* 23 */ {0, {154,4,155,480}, DIVIDELINE, x_("")},
2243  /* 24 */ {0, {292,4,308,302}, CHECK, N_("Only place entries that are DRC correct")}
2244 };
2245 static DIALOG us_arraydialog = {{50,75,367,565}, N_("Array Current Objects"), 0, 24, us_arraydialogitems, 0, 0};
2246 
2247 /* special items for the "array" dialog: */
2248 #define DARR_XREPEAT       3		/* X repeat factor (edit text) */
2249 #define DARR_YREPEAT       4		/* Y repeat factor (edit text) */
2250 #define DARR_XSPACING      5		/* X spacing (edit text) */
2251 #define DARR_YSPACING      6		/* Y spacing (edit text) */
2252 #define DARR_ADDNAMES      7		/* Add names (check) */
2253 #define DARR_FLIPX         8		/* Flip in X (check) */
2254 #define DARR_FLIPY         9		/* Flip in Y (check) */
2255 #define DARR_XSPACING_L   12		/* X spacing label (message) */
2256 #define DARR_YSPACING_L   13		/* Y spacing label (message) */
2257 #define DARR_SPACEEDGE    14		/* Space by edge (radio) */
2258 #define DARR_SPACECENTER  15		/* Space by center (radio) */
2259 #define DARR_STAGGERX     16		/* Stagger in X (check) */
2260 #define DARR_STAGGERY     17		/* Stagger in Y (check) */
2261 #define DARR_SPACECHARSP  18		/* Space by char. spacing (radio) */
2262 #define DARR_SPACEMEASURE 19		/* Space by measured dist (radio) */
2263 #define DARR_LINEARDIAG   20		/* Linear diagonal array (check) */
2264 #define DARR_CENTERX      21		/* Center in X (check) */
2265 #define DARR_CENTERY      22		/* Center in Y (check) */
2266 #define DARR_ONLYDRCGOOD  24		/* Only place DRC-clean entries (check) */
2267 
us_arraydlog(CHAR * paramstart[])2268 INTBIG us_arraydlog(CHAR *paramstart[])
2269 {
2270 	REGISTER INTBIG itemHit, xcentdist, ycentdist, xsize, ysize, lx=0, hx=0, ly=0, hy=0, i,
2271 		chardistx=0, chardisty=0, curspacing, measdistx=0, measdisty=0, x, y,
2272 		thischarx, thischary, swap;
2273 	BOOLEAN xyrev, first, havechar;
2274 	INTBIG xoverlap, yoverlap;
2275 	static INTBIG lastXrepeat = 1, lastYrepeat = 1;
2276 	static INTBIG lastXdist = 0, lastYdist = 0;
2277 	static INTBIG lastspacing = DARR_SPACEEDGE;
2278 	static INTBIG lastXflip = 0, lastYflip = 0;
2279 	static INTBIG lastXcenter = 0, lastYcenter = 0;
2280 	static INTBIG lastXstagger = 0, lastYstagger = 0;
2281 	static INTBIG lastlineardiagonal = 0, lastaddnames = 0, lastdrcgood = 0;
2282 	REGISTER VARIABLE *var;
2283 	CHAR line[40];
2284 	REGISTER NODEINST *ni;
2285 	REGISTER ARCINST *ai;
2286 	REGISTER GEOM **list, *geom;
2287 	REGISTER NODEPROTO *np;
2288 	REGISTER void *infstr;
2289 	REGISTER void *dia;
2290 
2291 	/* get the objects to be arrayed */
2292 	list = us_gethighlighted(WANTNODEINST|WANTARCINST, 0, 0);
2293 	if (list[0] == NOGEOM)
2294 	{
2295 		us_abortcommand(_("Must select circuitry before arraying it"));
2296 		return(0);
2297 	}
2298 	np = geomparent(list[0]);
2299 
2300 	/* display the array dialog box */
2301 	dia = DiaInitDialog(&us_arraydialog);
2302 	if (dia == 0) return(0);
2303 	esnprintf(line, 40, x_("%ld"), lastXrepeat);   DiaSetText(dia, DARR_XREPEAT, line);
2304 	esnprintf(line, 40, x_("%ld"), lastYrepeat);   DiaSetText(dia, DARR_YREPEAT, line);
2305 	DiaSetControl(dia, DARR_FLIPX, lastXflip);
2306 	DiaSetControl(dia, DARR_FLIPY, lastYflip);
2307 	DiaSetControl(dia, DARR_CENTERX, lastXcenter);
2308 	DiaSetControl(dia, DARR_CENTERY, lastYcenter);
2309 	DiaSetControl(dia, DARR_STAGGERX, lastXstagger);
2310 	DiaSetControl(dia, DARR_STAGGERY, lastYstagger);
2311 	DiaSetControl(dia, DARR_ADDNAMES, lastaddnames);
2312 	DiaSetControl(dia, DARR_ONLYDRCGOOD, lastdrcgood);
2313 	DiaSetControl(dia, DARR_LINEARDIAG, lastlineardiagonal);
2314 
2315 	/* see if a single cell instance is selected (in which case DRC validity can be done) */
2316 	if (list[0] != NOGEOM && list[1] == NOGEOM && list[0]->entryisnode &&
2317 		list[0]->entryaddr.ni->proto->primindex == 0)
2318 			DiaUnDimItem(dia, DARR_ONLYDRCGOOD); else
2319 				DiaDimItem(dia, DARR_ONLYDRCGOOD);
2320 
2321 	/* see if a cell was selected which has a characteristic distance */
2322 	havechar = FALSE;
2323 	for(i=0; list[i] != NOGEOM; i++)
2324 	{
2325 		if (!list[i]->entryisnode) continue;
2326 		ni = list[i]->entryaddr.ni;
2327 		if (ni->proto->primindex != 0) continue;
2328 		var = getval((INTBIG)ni->proto, VNODEPROTO, VINTEGER|VISARRAY,
2329 			x_("FACET_characteristic_spacing"));
2330 		if (var == NOVARIABLE) continue;
2331 		thischarx = ((INTBIG *)var->addr)[0];
2332 		thischary = ((INTBIG *)var->addr)[1];
2333 		xyrev = FALSE;
2334 		if (ni->transpose == 0)
2335 		{
2336 			if (ni->rotation == 900 || ni->rotation == 2700) xyrev = TRUE;
2337 		} else
2338 		{
2339 			if (ni->rotation == 0 || ni->rotation == 1800) xyrev = TRUE;
2340 		}
2341 		if (xyrev)
2342 		{
2343 			swap = thischarx;   thischarx = thischary;   thischary = swap;
2344 		}
2345 
2346 		if (havechar)
2347 		{
2348 			/* LINTED "chardistx" and "chardisty" used in proper order */
2349 			if (chardistx != thischarx || chardisty != thischary)
2350 			{
2351 				havechar = FALSE;
2352 				break;
2353 			}
2354 		}
2355 		chardistx = thischarx;
2356 		chardisty = thischary;
2357 		havechar = TRUE;
2358 	}
2359 	if (havechar)
2360 	{
2361 		DiaUnDimItem(dia, DARR_SPACECHARSP);
2362 		if (lastspacing == DARR_SPACECHARSP)
2363 		{
2364 			lastXdist = chardistx;
2365 			lastYdist = chardisty;
2366 		}
2367 	} else
2368 	{
2369 		DiaDimItem(dia, DARR_SPACECHARSP);
2370 		if (lastspacing == DARR_SPACECHARSP)
2371 		{
2372 			lastspacing = DARR_SPACEEDGE;
2373 			lastXdist = lastYdist = 0;
2374 		}
2375 	}
2376 
2377 	/* see if there was a measured distance */
2378 	if (us_validmesaure)
2379 	{
2380 		DiaUnDimItem(dia, DARR_SPACEMEASURE);
2381 		measdistx = abs(us_lastmeasurex);
2382 		measdisty = abs(us_lastmeasurey);
2383 		if (lastspacing == DARR_SPACEMEASURE)
2384 		{
2385 			lastXdist = measdistx;
2386 			lastYdist = measdisty;
2387 		}
2388 	} else
2389 	{
2390 		DiaDimItem(dia, DARR_SPACEMEASURE);
2391 		if (lastspacing == DARR_SPACEMEASURE)
2392 		{
2393 			lastspacing = DARR_SPACEEDGE;
2394 			lastXdist = lastYdist = 0;
2395 		}
2396 	}
2397 
2398 	DiaSetText(dia, DARR_XSPACING, latoa(lastXdist, 0));
2399 	DiaSetText(dia, DARR_YSPACING, latoa(lastYdist, 0));
2400 	curspacing = lastspacing;
2401 	DiaSetControl(dia, curspacing, 1);
2402 	if (curspacing == DARR_SPACEEDGE)
2403 	{
2404 		DiaSetText(dia, DARR_XSPACING_L, _("X edge overlap:"));
2405 		DiaSetText(dia, DARR_YSPACING_L, _("Y edge overlap:"));
2406 	} else
2407 	{
2408 		DiaSetText(dia, DARR_XSPACING_L, _("X centerline distance:"));
2409 		DiaSetText(dia, DARR_YSPACING_L, _("Y centerline distance:"));
2410 	}
2411 
2412 	/* mark the list of nodes and arcs in the cell that will be arrayed */
2413 	for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2414 		ni->temp1 = 0;
2415 	for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2416 		ai->temp1 = 0;
2417 	for(i=0; list[i] != NOGEOM; i++)
2418 	{
2419 		geom = list[i];
2420 		if (geom->entryisnode)
2421 		{
2422 			ni = geom->entryaddr.ni;
2423 			ni->temp1 = 1;
2424 		} else
2425 		{
2426 			ai = geom->entryaddr.ai;
2427 			ai->temp1 = 1;
2428 			ai->end[0].nodeinst->temp1 = ai->end[1].nodeinst->temp1 = 1;
2429 		}
2430 	}
2431 
2432 	/* determine spacing between arrayed objects */
2433 	first = TRUE;
2434 	for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
2435 	{
2436 		if (ni->temp1 == 0) continue;
2437 		if (first)
2438 		{
2439 			lx = ni->geom->lowx;   hx = ni->geom->highx;
2440 			ly = ni->geom->lowy;   hy = ni->geom->highy;
2441 			first = FALSE;
2442 		} else
2443 		{
2444 			if (ni->geom->lowx < lx) lx = ni->geom->lowx;
2445 			if (ni->geom->highx > hx) hx = ni->geom->highx;
2446 			if (ni->geom->lowy < ly) ly = ni->geom->lowy;
2447 			if (ni->geom->highy > hy) hy = ni->geom->highy;
2448 		}
2449 	}
2450 	for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
2451 	{
2452 		if (ai->temp1 == 0) continue;
2453 		if (first)
2454 		{
2455 			lx = ai->geom->lowx;   hx = ai->geom->highx;
2456 			ly = ai->geom->lowy;   hy = ai->geom->highy;
2457 			first = FALSE;
2458 		} else
2459 		{
2460 			if (ai->geom->lowx < lx) lx = ai->geom->lowx;
2461 			if (ai->geom->highx > hx) hx = ai->geom->highx;
2462 			if (ai->geom->lowy < ly) ly = ai->geom->lowy;
2463 			if (ai->geom->highy > hy) hy = ai->geom->highy;
2464 		}
2465 	}
2466 	xsize = xcentdist = hx - lx;
2467 	ysize = ycentdist = hy - ly;
2468 	xoverlap = yoverlap = 0;
2469 
2470 	/* loop until done */
2471 	for(;;)
2472 	{
2473 		itemHit = DiaNextHit(dia);
2474 		if (itemHit == CANCEL) break;
2475 		if (itemHit == OK &&
2476 			DiaValidEntry(dia, DARR_XREPEAT) && DiaValidEntry(dia, DARR_YREPEAT) &&
2477 			DiaValidEntry(dia, DARR_XSPACING) && DiaValidEntry(dia, DARR_YSPACING)) break;
2478 		if (itemHit == DARR_ADDNAMES || itemHit == DARR_FLIPX ||
2479 			itemHit == DARR_FLIPY || itemHit == DARR_STAGGERX ||
2480 			itemHit == DARR_STAGGERY || itemHit == DARR_LINEARDIAG ||
2481 			itemHit == DARR_CENTERX || itemHit == DARR_CENTERY ||
2482 			itemHit == DARR_ONLYDRCGOOD)
2483 				DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
2484 		if (itemHit == DARR_SPACEEDGE || itemHit == DARR_SPACECENTER ||
2485 			itemHit == DARR_SPACECHARSP || itemHit == DARR_SPACEMEASURE)
2486 		{
2487 			DiaSetControl(dia, DARR_SPACEEDGE, 0);
2488 			DiaSetControl(dia, DARR_SPACECENTER, 0);
2489 			DiaSetControl(dia, DARR_SPACECHARSP, 0);
2490 			DiaSetControl(dia, DARR_SPACEMEASURE, 0);
2491 			DiaSetControl(dia, itemHit, 1);
2492 			x = atola(DiaGetText(dia, DARR_XSPACING), 0);   y = atola(DiaGetText(dia, DARR_YSPACING), 0);
2493 			switch (curspacing)
2494 			{
2495 				case DARR_SPACEEDGE:   xoverlap = x;    yoverlap = y;    break;
2496 				case DARR_SPACECENTER: xcentdist = x;   ycentdist = y;   break;
2497 			}
2498 			curspacing = itemHit;
2499 			if (curspacing == DARR_SPACEEDGE)
2500 			{
2501 				DiaSetText(dia, DARR_XSPACING_L, _("X edge overlap:"));
2502 				DiaSetText(dia, DARR_YSPACING_L, _("Y edge overlap:"));
2503 			} else
2504 			{
2505 				DiaSetText(dia, DARR_XSPACING_L, _("X centerline distance:"));
2506 				DiaSetText(dia, DARR_YSPACING_L, _("Y centerline distance:"));
2507 			}
2508 			switch (curspacing)
2509 			{
2510 				case DARR_SPACEEDGE:    x = xoverlap;    y = yoverlap;    break;
2511 				case DARR_SPACECENTER:  x = xcentdist;   y = ycentdist;   break;
2512 				case DARR_SPACECHARSP:  x = chardistx;   y = chardisty;   break;
2513 				case DARR_SPACEMEASURE: x = measdistx;   y = measdisty;   break;
2514 			}
2515 			DiaSetText(dia, DARR_XSPACING, latoa(x, 0));
2516 			DiaSetText(dia, DARR_YSPACING, latoa(y, 0));
2517 			continue;
2518 		}
2519 	}
2520 	lastXrepeat = eatoi(DiaGetText(dia, DARR_XREPEAT));
2521 	lastYrepeat = eatoi(DiaGetText(dia, DARR_YREPEAT));
2522 	lastXdist = atola(DiaGetText(dia, DARR_XSPACING), 0);
2523 	lastYdist = atola(DiaGetText(dia, DARR_YSPACING), 0);
2524 	lastXflip = DiaGetControl(dia, DARR_FLIPX);
2525 	lastYflip = DiaGetControl(dia, DARR_FLIPY);
2526 	lastXcenter = DiaGetControl(dia, DARR_CENTERX);
2527 	lastYcenter = DiaGetControl(dia, DARR_CENTERY);
2528 	lastXstagger = DiaGetControl(dia, DARR_STAGGERX);
2529 	lastYstagger = DiaGetControl(dia, DARR_STAGGERY);
2530 	lastaddnames = DiaGetControl(dia, DARR_ADDNAMES);
2531 	lastdrcgood = DiaGetControl(dia, DARR_ONLYDRCGOOD);
2532 	lastlineardiagonal = DiaGetControl(dia, DARR_LINEARDIAG);
2533 	lastspacing = curspacing;
2534 
2535 	paramstart[0] = x_("");
2536 	if (itemHit != CANCEL)
2537 	{
2538 		infstr = initinfstr();
2539 		addstringtoinfstr(infstr, DiaGetText(dia, DARR_XREPEAT));
2540 		if (lastXflip != 0) addtoinfstr(infstr, 'f');
2541 		if (lastXstagger != 0) addtoinfstr(infstr, 's');
2542 		if (lastXcenter != 0) addtoinfstr(infstr, 'c');
2543 		addtoinfstr(infstr, ' ');
2544 		addstringtoinfstr(infstr, DiaGetText(dia, DARR_YREPEAT));
2545 		if (lastYflip != 0) addtoinfstr(infstr, 'f');
2546 		if (lastYstagger != 0) addtoinfstr(infstr, 's');
2547 		if (lastYcenter != 0) addtoinfstr(infstr, 'c');
2548 		addtoinfstr(infstr, ' ');
2549 		xoverlap = lastXdist;
2550 		yoverlap = lastYdist;
2551 		if (DiaGetControl(dia, DARR_SPACEEDGE) == 0)
2552 		{
2553 			xoverlap = xsize - xoverlap;
2554 			yoverlap = ysize - yoverlap;
2555 		}
2556 		addstringtoinfstr(infstr, latoa(xoverlap, 0));
2557 		addtoinfstr(infstr, ' ');
2558 		addstringtoinfstr(infstr, latoa(yoverlap, 0));
2559 		if (lastaddnames == 0) addstringtoinfstr(infstr, x_(" no-names"));
2560 		if (lastlineardiagonal != 0) addstringtoinfstr(infstr, x_(" diagonal"));
2561 		if (lastdrcgood != 0) addstringtoinfstr(infstr, x_(" only-drc-valid"));
2562 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
2563 		allocstring(&us_returneddialogstring, returninfstr(infstr), us_tool->cluster);
2564 		paramstart[0] = us_returneddialogstring;
2565 	}
2566 	DiaDoneDialog(dia);
2567 	return(1);
2568 }
2569 
2570 /*************************** "ARTWORK COLOR" AND "LAYER DISPLAY" DIALOGS ***************************/
2571 
2572 /* Layer Patterns */
2573 static UCHAR1 us_icon300[] =
2574 {
2575 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2576 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2577 	0210, 0210, 0210, 0210, 0104, 0104, 021, 021, 042, 042, 042, 042, 021, 021, 0104, 0104,
2578 	0210, 0210, 0210, 0210, 0104, 0104, 021, 021, 042, 042, 042, 042, 021, 021, 0104, 0104,
2579 	0210, 0210, 0210, 0210, 0104, 0104, 021, 021, 042, 042, 042, 042, 021, 021, 0104, 0104,
2580 	0210, 0210, 0210, 0210, 0104, 0104, 021, 021, 042, 042, 042, 042, 021, 021, 0104, 0,
2581 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2582 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2583 };
2584 static UCHAR1 us_icon301[] =
2585 {
2586 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2587 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2588 	0314, 0314, 0377, 0377, 0314, 0314, 0, 0, 063, 063, 0377, 0377, 063, 063, 0, 0,
2589 	0314, 0314, 0377, 0377, 0314, 0314, 0, 0, 063, 063, 0377, 0377, 063, 063, 0, 0,
2590 	0314, 0314, 0377, 0377, 0314, 0314, 0, 0, 063, 063, 0377, 0377, 063, 063, 0, 0,
2591 	0314, 0314, 0377, 0377, 0314, 0314, 0, 0, 063, 063, 0377, 0377, 063, 063, 0, 0,
2592 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2593 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2594 };
2595 static UCHAR1 us_icon302[] =
2596 {
2597 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2598 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2599 	0125, 0125, 0140, 0140, 0125, 0125, 0220, 0220, 0125, 0125, 0220, 0220, 0125, 0125, 0140, 0140,
2600 	0125, 0125, 06, 06, 0125, 0125, 011, 011, 0125, 0125, 011, 011, 0125, 0125, 06, 06,
2601 	0125, 0125, 0140, 0140, 0125, 0125, 0220, 0220, 0125, 0125, 0220, 0220, 0125, 0125, 0140, 0140,
2602 	0125, 0125, 06, 06, 0125, 0125, 011, 011, 0125, 0125, 011, 011, 0, 0, 06, 06,
2603 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2604 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2605 };
2606 static UCHAR1 us_icon303[] =
2607 {
2608 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2609 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2610 	042, 042, 0104, 0104, 0, 0, 021, 021, 0210, 0210, 0104, 0104, 0, 0, 021, 021,
2611 	042, 042, 0104, 0104, 0, 0, 021, 021, 0210, 0210, 0104, 0104, 0, 0, 021, 021,
2612 	042, 042, 0104, 0104, 0, 0, 021, 021, 0210, 0210, 0104, 0104, 0, 0, 021, 021,
2613 	042, 042, 0104, 0104, 0, 0, 021, 021, 0210, 0210, 0104, 0104, 0, 0, 021, 021,
2614 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2615 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2616 };
2617 static UCHAR1 us_icon304[] =
2618 {
2619 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2620 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2621 	020, 020, 04, 04, 040, 040, 02, 02, 0100, 0100, 01, 01, 0200, 0200, 0200, 0200,
2622 	01, 01, 0100, 0100, 02, 02, 040, 040, 04, 04, 020, 020, 010, 010, 010, 010,
2623 	020, 020, 04, 04, 040, 040, 02, 02, 0100, 0100, 01, 01, 0200, 0200, 0200, 0200,
2624 	01, 01, 0100, 0100, 02, 02, 040, 040, 04, 04, 020, 020, 010, 010, 010, 010,
2625 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2626 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2627 };
2628 static UCHAR1 us_icon305[] =
2629 {
2630 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2631 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2632 	0100, 0100, 020, 0, 0200, 0200, 0, 040, 01, 01, 0100, 0, 02, 02, 0, 0200,
2633 	01, 01, 0, 01, 0200, 0200, 02, 0, 0100, 0100, 0, 04, 040, 040, 010, 0,
2634 	0100, 0100, 0, 020, 0200, 0200, 040, 0, 01, 01, 0, 0100, 02, 02, 0200, 0,
2635 	01, 01, 01, 0, 0200, 0200, 0, 02, 0100, 0100, 04, 0, 040, 040, 0, 010,
2636 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2637 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2638 };
2639 static UCHAR1 us_icon306[] =
2640 {
2641 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2642 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2643 	010, 0, 0, 0, 0, 04, 03, 03, 02, 0, 0204, 0204, 0, 01, 03, 03,
2644 	0, 0200, 0, 0, 0100, 0, 060, 060, 0, 040, 0110, 0110, 020, 0, 060, 060,
2645 	0, 010, 0, 0, 04, 0, 03, 03, 0, 02, 0204, 0204, 01, 0, 03, 03,
2646 	0200, 0, 0, 0, 0, 0100, 060, 060, 040, 0, 0110, 0110, 0, 020, 060, 060,
2647 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2648 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2649 };
2650 static UCHAR1 us_icon307[] =
2651 {
2652 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2653 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2654 	034, 034, 0, 0, 076, 076, 0314, 0314, 066, 066, 0, 0, 076, 076, 0314, 0314,
2655 	034, 034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2656 	034, 034, 0, 0, 076, 076, 0314, 0314, 066, 066, 0, 0, 076, 076, 0314, 0314,
2657 	034, 034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2658 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2659 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2660 };
2661 static UCHAR1 us_icon308[] =
2662 {
2663 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2664 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2665 	0, 0, 0, 0, 0, 0, 0, 0, 042, 042, 021, 021, 0210, 0210, 0, 0,
2666 	0, 0, 0, 0, 0, 0, 0, 0, 042, 042, 021, 021, 0210, 0210, 0, 0,
2667 	0, 0, 0, 0, 0, 0, 0, 0, 042, 042, 021, 021, 0210, 0210, 0, 0,
2668 	0, 0, 0, 0, 0, 0, 0, 0, 042, 042, 021, 021, 0210, 0210, 0, 0,
2669 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2670 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2671 };
2672 static UCHAR1 us_icon309[] =
2673 {
2674 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2675 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2676 	0, 0, 0, 0, 042, 042, 042, 042, 0104, 0104, 0125, 0125, 0210, 0210, 042, 042,
2677 	0, 0, 0, 0, 042, 042, 042, 042, 0104, 0104, 0125, 0125, 0210, 0210, 042, 042,
2678 	0, 0, 0, 0, 042, 042, 042, 042, 0104, 0104, 0125, 0125, 0210, 0210, 042, 042,
2679 	0, 0, 0, 0, 042, 042, 042, 042, 0104, 0104, 0125, 0125, 0210, 0210, 042, 042,
2680 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2681 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2682 };
2683 static UCHAR1 us_icon310[] =
2684 {
2685 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2686 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2687 	0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377,
2688 	0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377,
2689 	0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377,
2690 	0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377, 0, 0, 0377, 0377,
2691 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2692 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2693 };
2694 UINTSML us_predefpats[] =
2695 {
2696 	0x8888,  /* X   X   X   X    */
2697 	0x4444,  /*  X   X   X   X   */
2698 	0x2222,  /*   X   X   X   X  */
2699 	0x1111,  /*    X   X   X   X */
2700 	0x8888,  /* X   X   X   X    */
2701 	0x4444,  /*  X   X   X   X   */
2702 	0x2222,  /*   X   X   X   X  */
2703 	0x1111,  /*    X   X   X   X */
2704 	0x8888,  /* X   X   X   X    */
2705 	0x4444,  /*  X   X   X   X   */
2706 	0x2222,  /*   X   X   X   X  */
2707 	0x1111,  /*    X   X   X   X */
2708 	0x8888,  /* X   X   X   X    */
2709 	0x4444,  /*  X   X   X   X   */
2710 	0x2222,  /*   X   X   X   X  */
2711 	0x1111,  /*    X   X   X   X */
2712 
2713 	0x8888,  /* X   X   X   X    */
2714 	0x1111,  /*    X   X   X   X */
2715 	0x2222,  /*   X   X   X   X  */
2716 	0x4444,  /*  X   X   X   X   */
2717 	0x8888,  /* X   X   X   X    */
2718 	0x1111,  /*    X   X   X   X */
2719 	0x2222,  /*   X   X   X   X  */
2720 	0x4444,  /*  X   X   X   X   */
2721 	0x8888,  /* X   X   X   X    */
2722 	0x1111,  /*    X   X   X   X */
2723 	0x2222,  /*   X   X   X   X  */
2724 	0x4444,  /*  X   X   X   X   */
2725 	0x8888,  /* X   X   X   X    */
2726 	0x1111,  /*    X   X   X   X */
2727 	0x2222,  /*   X   X   X   X  */
2728 	0x4444,  /*  X   X   X   X   */
2729 
2730 	0xCCCC,  /* XX  XX  XX  XX   */
2731 	0xCCCC,  /* XX  XX  XX  XX   */
2732 	0x3333,  /*   XX  XX  XX  XX */
2733 	0x3333,  /*   XX  XX  XX  XX */
2734 	0xCCCC,  /* XX  XX  XX  XX   */
2735 	0xCCCC,  /* XX  XX  XX  XX   */
2736 	0x3333,  /*   XX  XX  XX  XX */
2737 	0x3333,  /*   XX  XX  XX  XX */
2738 	0xCCCC,  /* XX  XX  XX  XX   */
2739 	0xCCCC,  /* XX  XX  XX  XX   */
2740 	0x3333,  /*   XX  XX  XX  XX */
2741 	0x3333,  /*   XX  XX  XX  XX */
2742 	0xCCCC,  /* XX  XX  XX  XX   */
2743 	0xCCCC,  /* XX  XX  XX  XX   */
2744 	0x3333,  /*   XX  XX  XX  XX */
2745 	0x3333,  /*   XX  XX  XX  XX */
2746 
2747 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2748 	0x0000,  /*                  */
2749 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2750 	0x0000,  /*                  */
2751 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2752 	0x0000,  /*                  */
2753 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2754 	0x0000,  /*                  */
2755 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2756 	0x0000,  /*                  */
2757 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2758 	0x0000,  /*                  */
2759 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2760 	0x0000,  /*                  */
2761 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
2762 	0x0000,  /*                  */
2763 
2764 	0xAAAA,  /* X X X X X X X X  */
2765 	0xAAAA,  /* X X X X X X X X  */
2766 	0xAAAA,  /* X X X X X X X X  */
2767 	0xAAAA,  /* X X X X X X X X  */
2768 	0xAAAA,  /* X X X X X X X X  */
2769 	0xAAAA,  /* X X X X X X X X  */
2770 	0xAAAA,  /* X X X X X X X X  */
2771 	0xAAAA,  /* X X X X X X X X  */
2772 	0xAAAA,  /* X X X X X X X X  */
2773 	0xAAAA,  /* X X X X X X X X  */
2774 	0xAAAA,  /* X X X X X X X X  */
2775 	0xAAAA,  /* X X X X X X X X  */
2776 	0xAAAA,  /* X X X X X X X X  */
2777 	0xAAAA,  /* X X X X X X X X  */
2778 	0xAAAA,  /* X X X X X X X X  */
2779 	0xAAAA,  /* X X X X X X X X  */
2780 
2781 	0x6060,  /*  XX      XX      */
2782 	0x9090,  /* X  X    X  X     */
2783 	0x9090,  /* X  X    X  X     */
2784 	0x6060,  /*  XX      XX      */
2785 	0x0606,  /*      XX      XX  */
2786 	0x0909,  /*     X  X    X  X */
2787 	0x0909,  /*     X  X    X  X */
2788 	0x0606,  /*      XX      XX  */
2789 	0x6060,  /*  XX      XX      */
2790 	0x9090,  /* X  X    X  X     */
2791 	0x9090,  /* X  X    X  X     */
2792 	0x6060,  /*  XX      XX      */
2793 	0x0606,  /*      XX      XX  */
2794 	0x0909,  /*     X  X    X  X */
2795 	0x0909,  /*     X  X    X  X */
2796 	0x0606,  /*      XX      XX  */
2797 
2798 	0x2222,  /*   X   X   X   X  */
2799 	0x0000,  /*                  */
2800 	0x8888,  /* X   X   X   X    */
2801 	0x0000,  /*                  */
2802 	0x2222,  /*   X   X   X   X  */
2803 	0x0000,  /*                  */
2804 	0x8888,  /* X   X   X   X    */
2805 	0x0000,  /*                  */
2806 	0x2222,  /*   X   X   X   X  */
2807 	0x0000,  /*                  */
2808 	0x8888,  /* X   X   X   X    */
2809 	0x0000,  /*                  */
2810 	0x2222,  /*   X   X   X   X  */
2811 	0x0000,  /*                  */
2812 	0x8888,  /* X   X   X   X    */
2813 	0x0000,  /*                  */
2814 
2815 	0x4444,  /*  X   X   X   X   */
2816 	0x1111,  /*    X   X   X   X */
2817 	0x4444,  /*  X   X   X   X   */
2818 	0x1111,  /*    X   X   X   X */
2819 	0x4444,  /*  X   X   X   X   */
2820 	0x1111,  /*    X   X   X   X */
2821 	0x4444,  /*  X   X   X   X   */
2822 	0x1111,  /*    X   X   X   X */
2823 	0x4444,  /*  X   X   X   X   */
2824 	0x1111,  /*    X   X   X   X */
2825 	0x4444,  /*  X   X   X   X   */
2826 	0x1111,  /*    X   X   X   X */
2827 	0x4444,  /*  X   X   X   X   */
2828 	0x1111,  /*    X   X   X   X */
2829 	0x4444,  /*  X   X   X   X   */
2830 	0x1111,  /*    X   X   X   X */
2831 
2832 	0x1010,  /*    X       X     */
2833 	0x2020,  /*   X       X      */
2834 	0x4040,  /*  X       X       */
2835 	0x8080,  /* X       X        */
2836 	0x0101,  /*        X       X */
2837 	0x0202,  /*       X       X  */
2838 	0x0404,  /*      X       X   */
2839 	0x0808,  /*     X       X    */
2840 	0x1010,  /*    X       X     */
2841 	0x2020,  /*   X       X      */
2842 	0x4040,  /*  X       X       */
2843 	0x8080,  /* X       X        */
2844 	0x0101,  /*        X       X */
2845 	0x0202,  /*       X       X  */
2846 	0x0404,  /*      X       X   */
2847 	0x0808,  /*     X       X    */
2848 
2849 	0x0808,  /*     X       X    */
2850 	0x0404,  /*      X       X   */
2851 	0x0202,  /*       X       X  */
2852 	0x0101,  /*        X       X */
2853 	0x8080,  /* X       X        */
2854 	0x4040,  /*  X       X       */
2855 	0x2020,  /*   X       X      */
2856 	0x1010,  /*    X       X     */
2857 	0x0808,  /*     X       X    */
2858 	0x0404,  /*      X       X   */
2859 	0x0202,  /*       X       X  */
2860 	0x0101,  /*        X       X */
2861 	0x8080,  /* X       X        */
2862 	0x4040,  /*  X       X       */
2863 	0x2020,  /*   X       X      */
2864 	0x1010,  /*    X       X     */
2865 
2866 	0x4040,  /*  X       X       */
2867 	0x8080,  /* X       X        */
2868 	0x0101,  /*        X       X */
2869 	0x0202,  /*       X       X  */
2870 	0x0101,  /*        X       X */
2871 	0x8080,  /* X       X        */
2872 	0x4040,  /*  X       X       */
2873 	0x2020,  /*   X       X      */
2874 	0x4040,  /*  X       X       */
2875 	0x8080,  /* X       X        */
2876 	0x0101,  /*        X       X */
2877 	0x0202,  /*       X       X  */
2878 	0x0101,  /*        X       X */
2879 	0x8080,  /* X       X        */
2880 	0x4040,  /*  X       X       */
2881 	0x2020,  /*   X       X      */
2882 
2883 	0x2020,  /*   X       X      */
2884 	0x0000,  /*                  */
2885 	0x8080,  /* X       X        */
2886 	0x0000,  /*                  */
2887 	0x0202,  /*       X       X  */
2888 	0x0000,  /*                  */
2889 	0x0808,  /*     X       X    */
2890 	0x0000,  /*                  */
2891 	0x2020,  /*   X       X      */
2892 	0x0000,  /*                  */
2893 	0x8080,  /* X       X        */
2894 	0x0000,  /*                  */
2895 	0x0202,  /*       X       X  */
2896 	0x0000,  /*                  */
2897 	0x0808,  /*     X       X    */
2898 	0x0000,  /*                  */
2899 
2900 	0x0808,  /*     X       X    */
2901 	0x0000,  /*                  */
2902 	0x0202,  /*       X       X  */
2903 	0x0000,  /*                  */
2904 	0x8080,  /* X       X        */
2905 	0x0000,  /*                  */
2906 	0x2020,  /*   X       X      */
2907 	0x0000,  /*                  */
2908 	0x0808,  /*     X       X    */
2909 	0x0000,  /*                  */
2910 	0x0202,  /*       X       X  */
2911 	0x0000,  /*                  */
2912 	0x8080,  /* X       X        */
2913 	0x0000,  /*                  */
2914 	0x2020,  /*   X       X      */
2915 	0x0000,  /*                  */
2916 
2917 	0x0000,  /*                  */
2918 	0x0303,  /*       XX      XX */
2919 	0x4848,  /*  X  X    X  X    */
2920 	0x0303,  /*       XX      XX */
2921 	0x0000,  /*                  */
2922 	0x3030,  /*   XX      XX     */
2923 	0x8484,  /* X    X  X    X   */
2924 	0x3030,  /*   XX      XX     */
2925 	0x0000,  /*                  */
2926 	0x0303,  /*       XX      XX */
2927 	0x4848,  /*  X  X    X  X    */
2928 	0x0303,  /*       XX      XX */
2929 	0x0000,  /*                  */
2930 	0x3030,  /*   XX      XX     */
2931 	0x8484,  /* X    X  X    X   */
2932 	0x3030,  /*   XX      XX     */
2933 
2934 	0x1C1C,  /*    XXX     XXX   */
2935 	0x3E3E,  /*   XXXXX   XXXXX  */
2936 	0x3636,  /*   XX XX   XX XX  */
2937 	0x3E3E,  /*   XXXXX   XXXXX  */
2938 	0x1C1C,  /*    XXX     XXX   */
2939 	0x0000,  /*                  */
2940 	0x0000,  /*                  */
2941 	0x0000,  /*                  */
2942 	0x1C1C,  /*    XXX     XXX   */
2943 	0x3E3E,  /*   XXXXX   XXXXX  */
2944 	0x3636,  /*   XX XX   XX XX  */
2945 	0x3E3E,  /*   XXXXX   XXXXX  */
2946 	0x1C1C,  /*    XXX     XXX   */
2947 	0x0000,  /*                  */
2948 	0x0000,  /*                  */
2949 	0x0000,  /*                  */
2950 
2951 	0x0000,  /*                  */
2952 	0xCCCC,  /* XX  XX  XX  XX   */
2953 	0x0000,  /*                  */
2954 	0xCCCC,  /* XX  XX  XX  XX   */
2955 	0x0000,  /*                  */
2956 	0x0000,  /*                  */
2957 	0x0000,  /*                  */
2958 	0x0000,  /*                  */
2959 	0x0000,  /*                  */
2960 	0xCCCC,  /* XX  XX  XX  XX   */
2961 	0x0000,  /*                  */
2962 	0xCCCC,  /* XX  XX  XX  XX   */
2963 	0x0000,  /*                  */
2964 	0x0000,  /*                  */
2965 	0x0000,  /*                  */
2966 	0x0000,  /*                  */
2967 
2968 	0x0000,  /*                  */
2969 	0x0000,  /*                  */
2970 	0x2222,  /*   X   X   X   X  */
2971 	0x8888,  /* X   X   X   X    */
2972 	0x0000,  /*                  */
2973 	0x0000,  /*                  */
2974 	0x2222,  /*   X   X   X   X  */
2975 	0x8888,  /* X   X   X   X    */
2976 	0x0000,  /*                  */
2977 	0x0000,  /*                  */
2978 	0x2222,  /*   X   X   X   X  */
2979 	0x8888,  /* X   X   X   X    */
2980 	0x0000,  /*                  */
2981 	0x0000,  /*                  */
2982 	0x2222,  /*   X   X   X   X  */
2983 	0x8888,  /* X   X   X   X    */
2984 
2985 	0x0000,  /*                  */
2986 	0x0000,  /*                  */
2987 	0x1111,  /*    X   X   X   X */
2988 	0x0000,  /*                  */
2989 	0x0000,  /*                  */
2990 	0x0000,  /*                  */
2991 	0x1111,  /*    X   X   X   X */
2992 	0x0000,  /*                  */
2993 	0x0000,  /*                  */
2994 	0x0000,  /*                  */
2995 	0x1111,  /*    X   X   X   X */
2996 	0x0000,  /*                  */
2997 	0x0000,  /*                  */
2998 	0x0000,  /*                  */
2999 	0x1111,  /*    X   X   X   X */
3000 	0x0000,  /*                  */
3001 
3002 	0x0000,  /*                  */
3003 	0x2222,  /*   X   X   X   X  */
3004 	0x4444,  /*  X   X   X   X   */
3005 	0x8888,  /* X   X   X   X    */
3006 	0x0000,  /*                  */
3007 	0x2222,  /*   X   X   X   X  */
3008 	0x4444,  /*  X   X   X   X   */
3009 	0x8888,  /* X   X   X   X    */
3010 	0x0000,  /*                  */
3011 	0x2222,  /*   X   X   X   X  */
3012 	0x4444,  /*  X   X   X   X   */
3013 	0x8888,  /* X   X   X   X    */
3014 	0x0000,  /*                  */
3015 	0x2222,  /*   X   X   X   X  */
3016 	0x4444,  /*  X   X   X   X   */
3017 	0x8888,  /* X   X   X   X    */
3018 
3019 	0x0000,  /*                  */
3020 	0x2222,  /*   X   X   X   X  */
3021 	0x5555,  /*  X X X X X X X X */
3022 	0x2222,  /*   X   X   X   X  */
3023 	0x0000,  /*                  */
3024 	0x2222,  /*   X   X   X   X  */
3025 	0x5555,  /*  X X X X X X X X */
3026 	0x2222,  /*   X   X   X   X  */
3027 	0x0000,  /*                  */
3028 	0x2222,  /*   X   X   X   X  */
3029 	0x5555,  /*  X X X X X X X X */
3030 	0x2222,  /*   X   X   X   X  */
3031 	0x0000,  /*                  */
3032 	0x2222,  /*   X   X   X   X  */
3033 	0x5555,  /*  X X X X X X X X */
3034 	0x2222,  /*   X   X   X   X  */
3035 
3036 	0x0000,  /*                  */
3037 	0x0000,  /*                  */
3038 	0x0000,  /*                  */
3039 	0x0000,  /*                  */
3040 	0x0000,  /*                  */
3041 	0x0000,  /*                  */
3042 	0x0000,  /*                  */
3043 	0x0000,  /*                  */
3044 	0x0000,  /*                  */
3045 	0x0000,  /*                  */
3046 	0x0000,  /*                  */
3047 	0x0000,  /*                  */
3048 	0x0000,  /*                  */
3049 	0x0000,  /*                  */
3050 	0x0000,  /*                  */
3051 	0x0000,  /*                  */
3052 
3053 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3054 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3055 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3056 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3057 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3058 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3059 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3060 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3061 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3062 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3063 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3064 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3065 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3066 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3067 	0xFFFF,  /* XXXXXXXXXXXXXXXX */
3068 	0xFFFF   /* XXXXXXXXXXXXXXXX */
3069 };
3070 
3071 #define DPATART_PATTERNAREA  4		/* Pattern squares for both dialogs (user item) */
3072 
3073 static RECTAREA us_strokerect;
3074 static INTBIG   us_origpattern[16];
3075 static BOOLEAN  us_strokeup;
3076 static BOOLEAN  us_patternchanged;
3077 
3078 static void us_redrawpattern(RECTAREA*, void *dia);
3079 static void us_patternstroke(INTBIG, INTBIG);
3080 
us_redrawpattern(RECTAREA * bigr,void * dia)3081 void us_redrawpattern(RECTAREA *bigr, void *dia)
3082 {
3083 	Q_UNUSED( bigr );
3084 	INTBIG j, k, bits;
3085 	RECTAREA r;
3086 
3087 	for(j=0; j<16; j++)
3088 	{
3089 		bits = us_origpattern[j] & 0xFFFF;
3090 		for(k=0; k<16; k++)
3091 		{
3092 			r.left = (INTSML)(us_strokerect.left + k*16);   r.right = r.left + 17;
3093 			r.top = (INTSML)(us_strokerect.top + j*16);     r.bottom = r.top + 17;
3094 			if ((bits & (1<<(15-k))) != 0) DiaDrawRect(dia, DPATART_PATTERNAREA, &r, 0, 0, 0); else
3095 				DiaFrameRect(dia, DPATART_PATTERNAREA, &r);
3096 		}
3097 	}
3098 }
3099 
us_patternstroke(INTBIG x,INTBIG y)3100 void us_patternstroke(INTBIG x, INTBIG y)
3101 {
3102 	REGISTER INTBIG j, k, bits;
3103 	RECTAREA r;
3104 
3105 	j = (y - us_strokerect.top) / 16;  if (j < 0) j = 0;  if (j > 15) j = 15;
3106 	k = (x - us_strokerect.left) / 16;  if (k < 0) k = 0;  if (k > 15) k = 15;
3107 	r.left = (INTSML)(us_strokerect.left + k*16);   r.right = r.left + 17;
3108 	r.top = (INTSML)(us_strokerect.top + j*16);     r.bottom = r.top + 17;
3109 	bits = us_origpattern[j] & 0xFFFF;
3110 	if (!us_strokeup)
3111 	{
3112 		DiaFrameRect(us_trackingdialog, DPATART_PATTERNAREA, &r);
3113 		bits &= ~(1<<(15-k));
3114 	} else
3115 	{
3116 		DiaDrawRect(us_trackingdialog, DPATART_PATTERNAREA, &r, 0, 0, 0);
3117 		bits |= 1<<(15-k);
3118 	}
3119 	us_origpattern[j] = bits;
3120 	us_patternchanged = TRUE;
3121 }
3122 
3123 /* Artwork Color */
3124 static DIALOGITEM us_artworkdialogitems[] =
3125 {
3126  /*  1 */ {0, {260,312,284,376}, BUTTON, N_("OK")},
3127  /*  2 */ {0, {216,312,240,376}, BUTTON, N_("Cancel")},
3128  /*  3 */ {0, {108,280,124,420}, RADIO, N_("Outlined Pattern")},
3129  /*  4 */ {0, {34,4,290,260}, USERDRAWN, x_("")},
3130  /*  5 */ {0, {52,280,68,376}, RADIO, N_("Solid color")},
3131  /*  6 */ {0, {148,280,164,332}, MESSAGE, N_("Color:")},
3132  /*  7 */ {0, {80,280,96,376}, RADIO, N_("Use Pattern")},
3133  /*  8 */ {0, {0,8,32,40}, ICON, (CHAR *)us_icon300},
3134  /*  9 */ {0, {0,40,32,72}, ICON, (CHAR *)us_icon301},
3135  /* 10 */ {0, {0,72,32,104}, ICON, (CHAR *)us_icon302},
3136  /* 11 */ {0, {0,104,32,136}, ICON, (CHAR *)us_icon303},
3137  /* 12 */ {0, {0,136,32,168}, ICON, (CHAR *)us_icon304},
3138  /* 13 */ {0, {0,168,32,200}, ICON, (CHAR *)us_icon305},
3139  /* 14 */ {0, {0,200,32,232}, ICON, (CHAR *)us_icon306},
3140  /* 15 */ {0, {0,232,32,264}, ICON, (CHAR *)us_icon307},
3141  /* 16 */ {0, {0,264,32,296}, ICON, (CHAR *)us_icon308},
3142  /* 17 */ {0, {0,296,32,328}, ICON, (CHAR *)us_icon309},
3143  /* 18 */ {0, {0,328,32,360}, ICON, (CHAR *)us_icon310},
3144  /* 19 */ {0, {168,280,184,420}, POPUP, x_("")}
3145 };
3146 static DIALOG us_artworkdialog = {{50,75,349,505}, N_("Set Look of Highlighted"), 0, 19, us_artworkdialogitems, 0, 0};
3147 
3148 /* special items for the "artwork color" dialog: */
3149 #define DART_OUTLINE      3		/* Outline pattern (radio) */
3150 #define DART_SOLID        5		/* Solid (radio) */
3151 #define DART_PATTERN      7		/* Use Pattern (radio) */
3152 #define DART_PREPATFIRST  8		/* First predefined pattern (user item) */
3153 #define DART_PREPATLAST  18		/* Last predefined pattern (user item) */
3154 #define DART_COLOR       19		/* Color (popup) */
3155 
us_artlookdlog(void)3156 INTBIG us_artlookdlog(void)
3157 {
3158 	RECTAREA r;
3159 	INTBIG addr, type, x, y;
3160 	REGISTER INTBIG i, j, k, bits, itemHit, len;
3161 	UINTSML spattern[16];
3162 	REGISTER BOOLEAN foundart;
3163 	REGISTER GEOM **list;
3164 	REGISTER NODEINST *ni;
3165 	REGISTER ARCINST *ai;
3166 	REGISTER VARIABLE *var;
3167 	CHAR *newlang[25], *colorname, *colorsymbol;
3168 	REGISTER void *dia;
3169 
3170 	/* make sure there is an artwork primitive highlighted */
3171 	list = us_gethighlighted(WANTNODEINST|WANTARCINST, 0, 0);
3172 	if (list[0] == NOGEOM)
3173 	{
3174 		ttyputerr(M_("Nothing is selected"));
3175 		return(0);
3176 	}
3177 	foundart = FALSE;
3178 	for(i=0; list[i] != NOGEOM; i++)
3179 	{
3180 		if (list[i]->entryisnode)
3181 		{
3182 			ni = list[i]->entryaddr.ni;
3183 			if (ni->proto->primindex != 0 && ni->proto->tech == art_tech) foundart = TRUE;
3184 			addr = (INTBIG)ni;
3185 			type = VNODEINST;
3186 		} else
3187 		{
3188 			ai = list[i]->entryaddr.ai;
3189 			if (ai->proto->tech == art_tech) foundart = TRUE;
3190 			addr = (INTBIG)ai;
3191 			type = VARCINST;
3192 		}
3193 	}
3194 	if (!foundart)
3195 	{
3196 		us_abortcommand(_("First select nodes or arcs in the Artwork technology"));
3197 		return(0);
3198 	}
3199 
3200 	/* display the artwork dialog box */
3201 	dia = DiaInitDialog(&us_artworkdialog);
3202 	if (dia == 0) return(0);
3203 	for(i=0; i<25; i++)
3204 	{
3205 		(void)ecolorname(us_colorvaluelist[i], &colorname, &colorsymbol);
3206 		newlang[i] = TRANSLATE(colorname);
3207 	}
3208 	DiaSetPopup(dia, DART_COLOR, 25, newlang);
3209 	DiaItemRect(dia, DPATART_PATTERNAREA, &us_strokerect);
3210 	DiaRedispRoutine(dia, DPATART_PATTERNAREA, us_redrawpattern);
3211 	DiaFrameRect(dia, DPATART_PATTERNAREA, &us_strokerect);
3212 
3213 	/* set existing conditions */
3214 	var = getvalkey(addr, type, VINTEGER, art_colorkey);
3215 	if (var != NOVARIABLE)
3216 	{
3217 		for(i=0; i<25; i++) if (us_colorvaluelist[i] == var->addr)
3218 		{
3219 			DiaSetPopupEntry(dia, DART_COLOR, i);
3220 			break;
3221 		}
3222 	}
3223 	DiaSetControl(dia, DART_SOLID, 1);
3224 	for(i=0; i<16; i++) us_origpattern[i] = 0;
3225 	var = getvalkey(addr, type, -1, art_patternkey);
3226 	if (var != NOVARIABLE)
3227 	{
3228 		len = getlength(var);
3229 		if (len == 16 || len == 8)
3230 		{
3231 			DiaSetControl(dia, DART_SOLID, 0);
3232 			if ((var->type&VTYPE) == VINTEGER)
3233 			{
3234 				for(i=0; i<len; i++) us_origpattern[i] = ((UINTBIG *)var->addr)[i];
3235 				DiaSetControl(dia, DART_PATTERN, 1);
3236 			} else if ((var->type&VTYPE) == VSHORT)
3237 			{
3238 				for(i=0; i<len; i++) us_origpattern[i] = ((UINTSML *)var->addr)[i];
3239 				DiaSetControl(dia, DART_OUTLINE, 1);
3240 			}
3241 			if (len == 8)
3242 			{
3243 				for(i=0; i<8; i++) us_origpattern[i+8] = us_origpattern[i];
3244 			}
3245 		}
3246 	}
3247 	us_redrawpattern(&us_strokerect, dia);
3248 
3249 	/* loop until done */
3250 	us_patternchanged = FALSE;
3251 	for(;;)
3252 	{
3253 		itemHit = DiaNextHit(dia);
3254 		if (itemHit == CANCEL || itemHit == OK) break;
3255 		if (itemHit == DPATART_PATTERNAREA)
3256 		{
3257 			DiaGetMouse(dia, &x, &y);
3258 			j = (y - us_strokerect.top) / 16;  if (j < 0) j = 0;  if (j > 15) j = 15;
3259 			k = (x - us_strokerect.left) / 16;  if (k < 0) k = 0;  if (k > 15) k = 15;
3260 			bits = us_origpattern[j] & 0xFFFF;
3261 			if ((bits & (1<<(15-k))) != 0) us_strokeup = FALSE; else
3262 				us_strokeup = TRUE;
3263 			us_trackingdialog = dia;
3264 			DiaTrackCursor(dia, us_patternstroke);
3265 			continue;
3266 		}
3267 		if (itemHit == DART_SOLID || itemHit == DART_PATTERN || itemHit == DART_OUTLINE)
3268 		{
3269 			DiaSetControl(dia, DART_SOLID, 0);
3270 			DiaSetControl(dia, DART_PATTERN, 0);
3271 			DiaSetControl(dia, DART_OUTLINE, 0);
3272 			DiaSetControl(dia, itemHit, 1);
3273 			us_patternchanged = TRUE;
3274 			continue;
3275 		}
3276 		if (itemHit >= DART_PREPATFIRST && itemHit <= DART_PREPATLAST)
3277 		{
3278 			DiaGetMouse(dia, &x, &y);
3279 			DiaItemRect(dia, itemHit, &r);
3280 			j = (r.top+r.bottom)/2;
3281 			if (y < j-8 || y > j+8) continue;
3282 			i = (itemHit-DART_PREPATFIRST) * 2;
3283 			if (x > (r.left+r.right)/2) i++;
3284 			i *= 16;
3285 			for(j=0; j<16; j++) us_origpattern[j] = us_predefpats[i++] & 0xFFFF;
3286 			us_redrawpattern(&us_strokerect, dia);
3287 			us_patternchanged = TRUE;
3288 			continue;
3289 		}
3290 		if (itemHit == DART_COLOR)
3291 		{
3292 			us_patternchanged = TRUE;
3293 			continue;
3294 		}
3295 	}
3296 
3297 	if (itemHit != CANCEL && us_patternchanged)
3298 	{
3299 		/* prepare for change */
3300 		us_pushhighlight();
3301 		us_clearhighlightcount();
3302 		for(i=0; list[i] != NOGEOM; i++)
3303 		{
3304 			if (list[i]->entryisnode)
3305 			{
3306 				ni = list[i]->entryaddr.ni;
3307 				if (ni->proto->primindex == 0 || ni->proto->tech != art_tech) continue;
3308 				addr = (INTBIG)ni;
3309 				type = VNODEINST;
3310 			} else
3311 			{
3312 				ai = list[i]->entryaddr.ai;
3313 				if (ai->proto->tech != art_tech) continue;
3314 				addr = (INTBIG)ai;
3315 				type = VARCINST;
3316 			}
3317 			startobjectchange(addr, type);
3318 
3319 			/* make the change */
3320 			if (DiaGetControl(dia, DART_SOLID) != 0)
3321 			{
3322 				var = getvalkey(addr, type, -1, art_patternkey);
3323 				if (var != NOVARIABLE) (void)delvalkey(addr, type, art_patternkey);
3324 			} else if (DiaGetControl(dia, DART_PATTERN) != 0)
3325 			{
3326 				(void)setvalkey(addr, type, art_patternkey, (INTBIG)us_origpattern,
3327 					VINTEGER|VISARRAY|(16<<VLENGTHSH));
3328 			} else
3329 			{
3330 				for(j=0; j<16; j++) spattern[j] = (UINTSML)us_origpattern[j];
3331 				(void)setvalkey(addr, type, art_patternkey, (INTBIG)spattern,
3332 					VSHORT|VISARRAY|(16<<VLENGTHSH));
3333 			}
3334 			j = DiaGetPopupEntry(dia, DART_COLOR);
3335 			if (us_colorvaluelist[j] == BLACK)
3336 			{
3337 				/* black is the default */
3338 				var = getvalkey(addr, type, VINTEGER, art_colorkey);
3339 				if (var != NOVARIABLE) (void)delvalkey(addr, type, art_colorkey);
3340 			} else (void)setvalkey(addr, type, art_colorkey, us_colorvaluelist[j], VINTEGER);
3341 
3342 			/* complete change */
3343 			endobjectchange(addr, type);
3344 		}
3345 		us_pophighlight(FALSE);
3346 	}
3347 	DiaDoneDialog(dia);
3348 	return(0);
3349 }
3350 
3351 /* Layer Display Options */
3352 static DIALOGITEM us_patterndialogitems[] =
3353 {
3354  /*  1 */ {0, {204,296,228,360}, BUTTON, N_("OK")},
3355  /*  2 */ {0, {164,296,188,360}, BUTTON, N_("Cancel")},
3356  /*  3 */ {0, {4,8,20,184}, MESSAGE, N_("Appearance of layer:")},
3357  /*  4 */ {0, {112,16,368,272}, USERDRAWN, x_("")},
3358  /*  5 */ {0, {4,184,20,368}, POPUP, x_("")},
3359  /*  6 */ {0, {64,184,80,336}, CHECK, N_("Outline Pattern")},
3360  /*  7 */ {0, {64,8,80,160}, CHECK, N_("Use Stipple Pattern")},
3361  /*  8 */ {0, {28,8,60,40}, ICON, (CHAR *)us_icon300},
3362  /*  9 */ {0, {28,40,60,72}, ICON, (CHAR *)us_icon301},
3363  /* 10 */ {0, {28,72,60,104}, ICON, (CHAR *)us_icon302},
3364  /* 11 */ {0, {28,104,60,136}, ICON, (CHAR *)us_icon303},
3365  /* 12 */ {0, {28,136,60,168}, ICON, (CHAR *)us_icon304},
3366  /* 13 */ {0, {28,168,60,200}, ICON, (CHAR *)us_icon305},
3367  /* 14 */ {0, {28,200,60,232}, ICON, (CHAR *)us_icon306},
3368  /* 15 */ {0, {28,232,60,264}, ICON, (CHAR *)us_icon307},
3369  /* 16 */ {0, {28,264,60,296}, ICON, (CHAR *)us_icon308},
3370  /* 17 */ {0, {28,296,60,328}, ICON, (CHAR *)us_icon309},
3371  /* 18 */ {0, {28,328,60,360}, ICON, (CHAR *)us_icon310},
3372  /* 19 */ {0, {88,184,104,368}, POPUP, x_("")},
3373  /* 20 */ {0, {88,8,104,184}, MESSAGE, N_("Color:")}
3374 };
3375 static DIALOG us_patterndialog = {{50,75,427,453}, N_("Layer Display Options"), 0, 20, us_patterndialogitems, 0, 0};
3376 
3377 /* special items for the "Layer Display Options" dialog: */
3378 #define DPAT_LAYER        5		/* Layer (popup) */
3379 #define DPAT_OUTLINE      6		/* Outline this layer (check) */
3380 #define DPAT_STIPPLE      7		/* Stipple this layer (check) */
3381 #define DPAT_PREPATFIRST  8		/* First predefined pattern (user item) */
3382 #define DPAT_PREPATLAST  18		/* Last predefined pattern (user item) */
3383 #define DPAT_COLOR       19		/* Color (popup) */
3384 
us_patterndlog(void)3385 INTBIG us_patterndlog(void)
3386 {
3387 	INTBIG itemHit, curlayer, i, j, k, newpat[18], x, y, bits, newcolor;
3388 	INTBIG *origbits, *orignature, *origcolor;
3389 	CHAR *colorname, *colorsymbol, *newlang[25];
3390 	BOOLEAN *origchanged, warnedofsolidopaque;
3391 	RECTAREA r;
3392 	REGISTER VARIABLE *var;
3393 	REGISTER CHAR **layernames;
3394 	REGISTER void *infstr;
3395 	REGISTER void *dia;
3396 
3397 	/* display the layer display options dialog box */
3398 	dia = DiaInitDialog(&us_patterndialog);
3399 	if (dia == 0) return(0);
3400 
3401 	/* get memory to save state */
3402 	origbits = (INTBIG *)emalloc(el_curtech->layercount * 16 * SIZEOFINTBIG, us_tool->cluster);
3403 	if (origbits == 0) return(0);
3404 	orignature = (INTBIG *)emalloc(el_curtech->layercount * SIZEOFINTBIG, us_tool->cluster);
3405 	if (orignature == 0) return(0);
3406 	origcolor = (INTBIG *)emalloc(el_curtech->layercount * SIZEOFINTBIG, us_tool->cluster);
3407 	if (origcolor == 0) return(0);
3408 	origchanged = (BOOLEAN *)emalloc(el_curtech->layercount * (sizeof (BOOLEAN)), us_tool->cluster);
3409 	if (origchanged == 0) return(0);
3410 	for(i=0; i<el_curtech->layercount; i++)
3411 	{
3412 		orignature[i] = (el_curtech->layers[i])->colstyle;
3413 		origcolor[i] = (el_curtech->layers[i])->col;
3414 		origchanged[i] = FALSE;
3415 		for(j=0; j<16; j++) origbits[i*16+j] = (el_curtech->layers[i])->raster[j];
3416 
3417 		/* see if there is an override */
3418 		infstr = initinfstr();
3419 		addstringtoinfstr(infstr, x_("TECH_layer_pattern_"));
3420 		addstringtoinfstr(infstr, layername(el_curtech, i));
3421 		var = getval((INTBIG)el_curtech, VTECHNOLOGY, VINTEGER|VISARRAY, returninfstr(infstr));
3422 		if (var != NOVARIABLE)
3423 		{
3424 			orignature[i] = ((INTBIG *)var->addr)[16];
3425 			for(j=0; j<16; j++) origbits[i*16+j] = ((INTBIG *)var->addr)[j];
3426 			if (getlength(var) > 17) origcolor[i] = ((INTBIG *)var->addr)[17];
3427 		}
3428 	}
3429 	curlayer = 0;
3430 	DiaItemRect(dia, DPATART_PATTERNAREA, &us_strokerect);
3431 	DiaRedispRoutine(dia, DPATART_PATTERNAREA, us_redrawpattern);
3432 	DiaFrameRect(dia, DPATART_PATTERNAREA, &us_strokerect);
3433 
3434 	/* setup list of layer names */
3435 	layernames = (CHAR **)emalloc(el_curtech->layercount * (sizeof (CHAR *)), el_tempcluster);
3436 	for(i=0; i<el_curtech->layercount; i++)
3437 		(void)allocstring(&layernames[i], layername(el_curtech, i), el_tempcluster);
3438 	DiaSetPopup(dia, DPAT_LAYER, el_curtech->layercount, layernames);
3439 	for(i=0; i<el_curtech->layercount; i++)
3440 		efree(layernames[i]);
3441 	efree((CHAR *)layernames);
3442 
3443 	/* setup list of color names */
3444 	for(i=0; i<25; i++)
3445 	{
3446 		(void)ecolorname(us_colorvaluelist[i], &colorname, &colorsymbol);
3447 		newlang[i] = TRANSLATE(colorname);
3448 	}
3449 	DiaSetPopup(dia, DPAT_COLOR, 25, newlang);
3450 
3451 	/* setup initial layer: number 0 */
3452 	curlayer = 0;
3453 	DiaSetPopupEntry(dia, DPAT_LAYER, curlayer);
3454 	if ((orignature[curlayer]&NATURE) == PATTERNED)
3455 	{
3456 		DiaUnDimItem(dia, DPAT_OUTLINE);
3457 		DiaSetControl(dia, DPAT_STIPPLE, 1);
3458 		if ((orignature[curlayer]&OUTLINEPAT) != 0) DiaSetControl(dia, DPAT_OUTLINE, 1);
3459 	} else DiaDimItem(dia, DPAT_OUTLINE);
3460 	for(j=0; j<16; j++) us_origpattern[j] = origbits[curlayer*16+j] & 0xFFFF;
3461 	for(j=0; j<25; j++) if (origcolor[curlayer] == us_colorvaluelist[j]) break;
3462 	if (j < 25) DiaSetPopupEntry(dia, DPAT_COLOR, j);
3463 	us_redrawpattern(&us_strokerect, dia);
3464 
3465 	/* loop until done */
3466 	warnedofsolidopaque = FALSE;
3467 	for(;;)
3468 	{
3469 		itemHit = DiaNextHit(dia);
3470 		if (itemHit == CANCEL) break;
3471 		if (itemHit == OK) break;
3472 		if (itemHit == DPAT_COLOR)
3473 		{
3474 			newcolor = us_colorvaluelist[DiaGetPopupEntry(dia, DPAT_COLOR)];
3475 			if ((newcolor&LAYERO) != 0 && (orignature[curlayer]&NATURE) == SOLIDC)
3476 			{
3477 				if (!warnedofsolidopaque)
3478 					DiaMessageInDialog(_("Warning: opaque layers should be stippled (make this layer be stippled or restore its transparent color)"));
3479 				warnedofsolidopaque = TRUE;
3480 			}
3481 			origcolor[curlayer] = newcolor;
3482 			origchanged[curlayer] = TRUE;
3483 			continue;
3484 		}
3485 		if (itemHit == DPAT_STIPPLE)
3486 		{
3487 			/* the "Use Stipple" box */
3488 			if (DiaGetControl(dia, DPAT_STIPPLE) == 0)
3489 			{
3490 				DiaSetControl(dia, DPAT_STIPPLE, 1);
3491 				DiaUnDimItem(dia, DPAT_OUTLINE);
3492 				orignature[curlayer] = (orignature[curlayer] & ~NATURE) | PATTERNED;
3493 			} else
3494 			{
3495 				/* layer becoming solid (not stippled) */
3496 				if ((origcolor[curlayer]&LAYERO) != 0)
3497 				{
3498 					if (!warnedofsolidopaque)
3499 						DiaMessageInDialog(_("Warning: opaque layers should be stippled (give this layer a transparent color, or restore stippling)"));
3500 					warnedofsolidopaque = TRUE;
3501 				}
3502 				DiaSetControl(dia, DPAT_STIPPLE, 0);
3503 				DiaSetControl(dia, DPAT_OUTLINE, 0);
3504 				DiaDimItem(dia, DPAT_OUTLINE);
3505 				orignature[curlayer] = (orignature[curlayer] & ~NATURE) | SOLIDC;
3506 			}
3507 			origchanged[curlayer] = TRUE;
3508 			continue;
3509 		}
3510 		if (itemHit == DPAT_OUTLINE)
3511 		{
3512 			/* the "Outline Pattern" box */
3513 			if (DiaGetControl(dia, DPAT_OUTLINE) == 0)
3514 			{
3515 				DiaSetControl(dia, DPAT_OUTLINE, 1);
3516 				orignature[curlayer] |= OUTLINEPAT;
3517 			} else
3518 			{
3519 				DiaSetControl(dia, DPAT_OUTLINE, 0);
3520 				orignature[curlayer] &= ~OUTLINEPAT;
3521 			}
3522 			origchanged[curlayer] = TRUE;
3523 			continue;
3524 		}
3525 		if (itemHit == DPAT_LAYER)
3526 		{
3527 			/* the layer popup */
3528 			curlayer = DiaGetPopupEntry(dia, DPAT_LAYER);
3529 			DiaSetControl(dia, DPAT_STIPPLE, 0);
3530 			DiaUnDimItem(dia, DPAT_OUTLINE);
3531 			DiaSetControl(dia, DPAT_OUTLINE, 0);
3532 			if ((orignature[curlayer]&NATURE) == PATTERNED)
3533 			{
3534 				DiaSetControl(dia, DPAT_STIPPLE, 1);
3535 				if ((orignature[curlayer]&OUTLINEPAT) != 0) DiaSetControl(dia, DPAT_OUTLINE, 1);
3536 			} else DiaDimItem(dia, DPAT_OUTLINE);
3537 			for(j=0; j<16; j++) us_origpattern[j] = origbits[curlayer*16+j] & 0xFFFF;
3538 			for(j=0; j<25; j++) if (origcolor[curlayer] == us_colorvaluelist[j]) break;
3539 			if (j < 25) DiaSetPopupEntry(dia, DPAT_COLOR, j);
3540 			us_redrawpattern(&us_strokerect, dia);
3541 			continue;
3542 		}
3543 		if (itemHit == DPATART_PATTERNAREA)
3544 		{
3545 			DiaGetMouse(dia, &x, &y);
3546 			j = (y - us_strokerect.top) / 16;  if (j < 0) j = 0;  if (j > 15) j = 15;
3547 			k = (x - us_strokerect.left) / 16;  if (k < 0) k = 0;  if (k > 15) k = 15;
3548 			bits = origbits[curlayer*16+j] & 0xFFFF;
3549 			if ((bits & (1<<(15-k))) != 0) us_strokeup = FALSE; else
3550 				us_strokeup = TRUE;
3551 			us_trackingdialog = dia;
3552 			DiaTrackCursor(dia, us_patternstroke);
3553 			for(j=0; j<16; j++) origbits[curlayer*16+j] = us_origpattern[j];
3554 			origchanged[curlayer] = TRUE;
3555 			continue;
3556 		}
3557 		if (itemHit >= DPAT_PREPATFIRST && itemHit <= DPAT_PREPATLAST)
3558 		{
3559 			DiaGetMouse(dia, &x, &y);
3560 			DiaItemRect(dia, itemHit, &r);
3561 			j = (r.top+r.bottom)/2;
3562 			if (y < j-8 || y > j+8) continue;
3563 			i = (itemHit-DPAT_PREPATFIRST) * 2;
3564 			if (x > (r.left+r.right)/2) i++;
3565 			i *= 16;
3566 			for(j=0; j<16; j++)
3567 			{
3568 				bits = us_predefpats[i++] & 0xFFFF;
3569 				origbits[curlayer*16+j] = bits;
3570 				us_origpattern[j] = bits;
3571 			}
3572 			us_redrawpattern(&us_strokerect, dia);
3573 			origchanged[curlayer] = TRUE;
3574 			continue;
3575 		}
3576 	}
3577 
3578 	if (itemHit != CANCEL)
3579 	{
3580 		for(i=0; i<el_curtech->layercount; i++)
3581 		{
3582 			if (!origchanged[i]) continue;
3583 			(el_curtech->layers[i])->colstyle = (INTSML)orignature[i];
3584 			(el_curtech->layers[i])->col = origcolor[i];
3585 			if (origcolor[i] == COLORT1 || origcolor[i] == COLORT2 || origcolor[i] == COLORT3 ||
3586 				origcolor[i] == COLORT4 || origcolor[i] == COLORT5)
3587 					(el_curtech->layers[i])->bits = origcolor[i]; else
3588 						(el_curtech->layers[i])->bits = LAYERO;
3589 			for(j=0; j<16; j++) (el_curtech->layers[i])->raster[j] = (INTSML)origbits[i*16+j];
3590 
3591 			/* save a shadow variable for this layer pattern */
3592 			for(j=0; j<16; j++) newpat[j] = origbits[i*16+j];
3593 			newpat[16] = orignature[i];
3594 			newpat[17] = origcolor[i];
3595 			infstr = initinfstr();
3596 			addstringtoinfstr(infstr, x_("TECH_layer_pattern_"));
3597 			addstringtoinfstr(infstr, layername(el_curtech, i));
3598 			(void)setval((INTBIG)el_curtech, VTECHNOLOGY, returninfstr(infstr),
3599 				(INTBIG)newpat, VINTEGER|VISARRAY|(18<<VLENGTHSH));
3600 		}
3601 	}
3602 	efree((CHAR *)origbits);
3603 	efree((CHAR *)orignature);
3604 	efree((CHAR *)origchanged);
3605 	DiaDoneDialog(dia);
3606 	return(0);
3607 }
3608 
3609 /****************************** ATTRIBUTE DIALOG ******************************/
3610 
3611 /* Attributes */
3612 static DIALOGITEM us_attrdialogitems[] =
3613 {
3614  /*  1 */ {0, {432,28,456,108}, BUTTON, N_("Done")},
3615  /*  2 */ {0, {148,216,164,332}, MESSAGE, N_("Attribute name:")},
3616  /*  3 */ {0, {8,8,24,300}, RADIO, N_("Cell")},
3617  /*  4 */ {0, {32,8,48,300}, RADIO, N_("Node")},
3618  /*  5 */ {0, {56,8,72,300}, RADIO, N_("Cell port")},
3619  /*  6 */ {0, {80,8,96,300}, RADIO, N_("Node port")},
3620  /*  7 */ {0, {104,8,120,300}, RADIO, N_("Arc")},
3621  /*  8 */ {0, {148,8,300,208}, SCROLL, x_("")},
3622  /*  9 */ {0, {148,336,164,504}, EDITTEXT, x_("")},
3623  /* 10 */ {0, {172,276,220,576}, EDITTEXT, x_("")},
3624  /* 11 */ {0, {320,216,336,364}, CHECK, N_("Instances inherit")},
3625  /* 12 */ {0, {172,216,188,272}, MESSAGE, N_("Value")},
3626  /* 13 */ {0, {112,492,128,576}, BUTTON, N_("Make Array")},
3627  /* 14 */ {0, {380,8,396,132}, BUTTON, N_("Delete Attribute")},
3628  /* 15 */ {0, {308,8,324,132}, BUTTON, N_("Create Attribute")},
3629  /* 16 */ {0, {356,8,372,132}, BUTTON, N_("Rename Attribute")},
3630  /* 17 */ {0, {332,8,348,132}, BUTTON, N_("Change Value")},
3631  /* 18 */ {0, {272,216,288,296}, MESSAGE, N_("X offset:")},
3632  /* 19 */ {0, {296,216,312,296}, MESSAGE, N_("Y offset:")},
3633  /* 20 */ {0, {272,420,304,452}, ICON, (CHAR *)us_icon200},
3634  /* 21 */ {0, {304,420,336,452}, ICON, (CHAR *)us_icon201},
3635  /* 22 */ {0, {336,420,368,452}, ICON, (CHAR *)us_icon202},
3636  /* 23 */ {0, {368,420,400,452}, ICON, (CHAR *)us_icon203},
3637  /* 24 */ {0, {400,420,432,452}, ICON, (CHAR *)us_icon205},
3638  /* 25 */ {0, {272,456,288,568}, RADIO, N_("Center")},
3639  /* 26 */ {0, {288,456,304,568}, RADIO, N_("Bottom")},
3640  /* 27 */ {0, {304,456,320,568}, RADIO, N_("Top")},
3641  /* 28 */ {0, {320,456,336,568}, RADIO, N_("Right")},
3642  /* 29 */ {0, {336,456,352,568}, RADIO, N_("Left")},
3643  /* 30 */ {0, {352,456,368,568}, RADIO, N_("Lower right")},
3644  /* 31 */ {0, {368,456,384,568}, RADIO, N_("Lower left")},
3645  /* 32 */ {0, {384,456,400,568}, RADIO, N_("Upper right")},
3646  /* 33 */ {0, {400,456,416,568}, RADIO, N_("Upper left")},
3647  /* 34 */ {0, {8,304,128,484}, SCROLL, x_("")},
3648  /* 35 */ {0, {440,236,456,404}, POPUP, x_("")},
3649  /* 36 */ {0, {12,492,28,564}, MESSAGE, N_("Array:")},
3650  /* 37 */ {0, {32,492,48,576}, BUTTON, N_("Add")},
3651  /* 38 */ {0, {52,492,68,576}, BUTTON, N_("Remove")},
3652  /* 39 */ {0, {72,492,88,576}, BUTTON, N_("Add All")},
3653  /* 40 */ {0, {92,492,108,576}, BUTTON, N_("Remove All")},
3654  /* 41 */ {0, {248,216,264,272}, MESSAGE, N_("Show:")},
3655  /* 42 */ {0, {248,276,264,532}, POPUP, x_("")},
3656  /* 43 */ {0, {224,324,240,576}, MESSAGE, x_("")},
3657  /* 44 */ {0, {224,216,240,324}, POPUP, x_("")},
3658  /* 45 */ {0, {136,8,137,576}, DIVIDELINE, x_("")},
3659  /* 46 */ {0, {272,300,288,380}, EDITTEXT, x_("")},
3660  /* 47 */ {0, {296,300,312,380}, EDITTEXT, x_("")},
3661  /* 48 */ {0, {368,248,384,408}, RADIO, N_("Points (max 63)")},
3662  /* 49 */ {0, {368,196,384,240}, EDITTEXT, x_("")},
3663  /* 50 */ {0, {392,248,408,408}, RADIO, N_("Lambda (max 127.75)")},
3664  /* 51 */ {0, {392,196,408,240}, EDITTEXT, x_("")},
3665  /* 52 */ {0, {416,144,432,228}, MESSAGE, N_("Text font:")},
3666  /* 53 */ {0, {416,236,432,404}, POPUP, x_("")},
3667  /* 54 */ {0, {424,456,440,528}, CHECK, N_("Italic")},
3668  /* 55 */ {0, {444,456,460,520}, CHECK, N_("Bold")},
3669  /* 56 */ {0, {464,456,480,532}, CHECK, N_("Underline")},
3670  /* 57 */ {0, {380,140,396,188}, MESSAGE, N_("Size:")},
3671  /* 58 */ {0, {440,144,456,228}, MESSAGE, N_("Rotation:")},
3672  /* 59 */ {0, {344,216,360,364}, CHECK, N_("Is Parameter")},
3673  /* 60 */ {0, {464,236,480,404}, POPUP, x_("")},
3674  /* 61 */ {0, {464,144,480,228}, MESSAGE, N_("Units:")}
3675 };
3676 static DIALOG us_attrdialog = {{75,75,564,660}, N_("Attributes"), 0, 61, us_attrdialogitems, 0, 0};
3677 
3678 static VARIABLE *us_attrfindvarname(INTBIG curcontrol, INTBIG numvar, VARIABLE *firstvar, void *dia);
3679 static void      us_attrgetfactors(INTBIG curcontrol, INTBIG addr, INTBIG *numvar, VARIABLE **firstvar);
3680 static void      us_attrloadchoices(INTBIG numvar, VARIABLE *firstvar, INTBIG curcontrol, void *dia);
3681 static CHAR     *us_attrmakevarname(INTBIG curcontrol, PORTPROTO *pp, CHAR *name);
3682 static CHAR     *us_attrgenportvalue(INTBIG curcontrol, INTBIG addr, INTBIG type, CHAR *attrname, NODEPROTO *np, CHAR *oldvalue);
3683 static void      us_attrsetportposition(VARIABLE *var, PORTPROTO *pp);
3684 static void      us_attrloadportlist(INTBIG curcontrol, void *dia);
3685 static void      us_attrselectattributeline(INTBIG curcontrol, INTBIG which, INTBIG numvar, VARIABLE *firstvar, void *dia);
3686 static void      us_attrtextposition(INTBIG curcontrol, UINTBIG *olddescript, UINTBIG *newdescript, void *dia);
3687 
3688 /* special items for the "attributes" dialog: */
3689 #define DATR_CELLATTRS       3		/* Current cell (radio) */
3690 #define DATR_NODEATTRS       4		/* Current node inst (radio) */
3691 #define DATR_EXPORTATTRS     5		/* Current portproto (radio) */
3692 #define DATR_PORTATTRS       6		/* Current portinst (radio) */
3693 #define DATR_ARCATTRS        7		/* Current network (radio) */
3694 #define DATR_ATTRLIST        8		/* Attribute list (scroll) */
3695 #define DATR_ATTRNAME        9		/* Attribute name (edit text) */
3696 #define DATR_ATTRVALUE      10		/* Attribute value (edit text) */
3697 #define DATR_INHERIT        11		/* Instances inherit (check) */
3698 #define DATR_ARRAYPORT      13		/* Array Port attribute (button) */
3699 #define DATR_DELETEATTR     14		/* Delete attribute (button) */
3700 #define DATR_CREATEATTR     15		/* Create attribute (button) */
3701 #define DATR_RENAMEATTR     16		/* Rename attribute (button) */
3702 #define DATR_CHANGEATTR     17		/* Change attribute value (button) */
3703 #define DATR_FIRSTICON      20		/* Icon: cent/bot (icon) */
3704 #define DATR_LASTICON       24		/* Icon: upper-left (icon) */
3705 #define DATR_FIRSTNAMEBUT   25		/* First attribute name button (radio) */
3706 #define DATR_NAMECENT       25		/* Attribute: centered (radio) */
3707 #define DATR_NAMEBOT        26		/* Attribute: bottom (radio) */
3708 #define DATR_NAMETOP        27		/* Attribute: top (radio) */
3709 #define DATR_NAMERIGHT      28		/* Attribute: right (radio) */
3710 #define DATR_NAMELEFT       29		/* Attribute: left (radio) */
3711 #define DATR_NAMELOWRIGHT   30		/* Attribute: lower-right (radio) */
3712 #define DATR_NAMELOWLEFT    31		/* Attribute: lower-left (radio) */
3713 #define DATR_NAMEUPRIGHT    32		/* Attribute: upper-right (radio) */
3714 #define DATR_NAMEUPLEFT     33		/* Attribute: upper-left (radio) */
3715 #define DATR_LASTNAMEBUT    33		/* Last attribute name button (radio) */
3716 #define DATR_PORTLIST       34		/* Port list (scroll) */
3717 #define DATR_ROTATION       35		/* Text rotation (popup) */
3718 #define DATR_ARRAY_L        36		/* Array label (stat text) */
3719 #define DATR_ADDPORT        37		/* Add port to array (button) */
3720 #define DATR_REMOVEPORT     38		/* Remove port from array (button) */
3721 #define DATR_ADDALLPORTS    39		/* Add all ports to array (button) */
3722 #define DATR_REMOVEALLPORTS 40		/* Remove all ports from array (button) */
3723 #define DATR_WHATTOSHOW     42		/* What to show (popup) */
3724 #define DATR_EVALUATION     43		/* Evaluation (stat text) */
3725 #define DATR_LANGUAGE       44		/* Language (popup) */
3726 #define DATR_XOFFSET        46		/* Attribute X offset (edit text) */
3727 #define DATR_YOFFSET        47		/* Attribute Y offset (edit text) */
3728 #define DATR_ABSTEXTSIZE_L  48		/* Absolute text size label (radio) */
3729 #define DATR_ABSTEXTSIZE    49		/* Absolute text size (edit text) */
3730 #define DATR_RELTEXTSIZE_L  50		/* Relative text size label (radio) */
3731 #define DATR_RELTEXTSIZE    51		/* Relative text size (edit text) */
3732 #define DATR_TEXTFACE_L     52		/* Text font label (stat text) */
3733 #define DATR_TEXTFACE       53		/* Text font (popup) */
3734 #define DATR_TEXTITALIC     54		/* Text italic (check) */
3735 #define DATR_TEXTBOLD       55		/* Text bold (check) */
3736 #define DATR_TEXTUNDERLINE  56		/* Text underline (check) */
3737 #define DATR_ISPARAMETER    59		/* Is parameter (check) */
3738 #define DATR_UNITS          60		/* Text units (popup) */
3739 static NODEPROTO *us_attrnodeprotoaddr;
3740 static NODEINST  *us_attrnodeinstaddr;
3741 static ARCINST   *us_attrarcinstaddr;
3742 static PORTPROTO *us_attrportprotoaddr, *us_attrexportprotoaddr;
3743 
us_attributesdlog(void)3744 INTBIG us_attributesdlog(void)
3745 {
3746 	REGISTER INTBIG itemHit, i, which, value, curcontrol, addr, type,
3747 		tempaddr, temptype, listlen;
3748 	INTBIG numvar, newval, newtype, newaddr;
3749 	UINTBIG descript[TEXTDESCRIPTSIZE];
3750 	INTBIG x, y;
3751 	RECTAREA r;
3752 	REGISTER NODEPROTO *proto;
3753 	REGISTER PORTPROTO *pp;
3754 	REGISTER PORTEXPINST *pe;
3755 	REGISTER VARIABLE *var, *newvar;
3756 	VARIABLE *firstvar;
3757 	CHAR *oldvalue, *newvarname, *attrname, *newlang[16], line[50];
3758 	REGISTER CHAR *pt, *newvalue, **languages;
3759 	HIGHLIGHT high;
3760 	REGISTER void *infstr;
3761 	REGISTER void *dia;
3762 
3763 	/* display the attributes dialog box */
3764 	us_attrnodeprotoaddr = us_needcell();
3765 	if (us_attrnodeprotoaddr == NONODEPROTO) return(0);
3766 	dia = DiaInitDialog(&us_attrdialog);
3767 	if (dia == 0) return(0);
3768 	DiaInitTextDialog(dia, DATR_ATTRLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
3769 		SCSELMOUSE|SCREPORT);
3770 	DiaInitTextDialog(dia, DATR_PORTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
3771 		SCSELMOUSE|SCREPORT);
3772 	languages = us_languagechoices();
3773 	DiaSetPopup(dia, DATR_LANGUAGE, 4, languages);
3774 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_rotationtypes[i]);
3775 	DiaSetPopup(dia, DATR_ROTATION, 4, newlang);
3776 	for(i=0; i<8; i++) newlang[i] = TRANSLATE(us_unitnames[i]);
3777 	DiaSetPopup(dia, DATR_UNITS, 8, newlang);
3778 	if (graphicshas(CANCHOOSEFACES))
3779 	{
3780 		DiaUnDimItem(dia, DATR_TEXTFACE_L);
3781 		us_setpopupface(DATR_TEXTFACE, 0, TRUE, dia);
3782 	} else
3783 	{
3784 		DiaDimItem(dia, DATR_TEXTFACE_L);
3785 	}
3786 	if (graphicshas(CANMODIFYFONTS))
3787 	{
3788 		DiaUnDimItem(dia, DATR_TEXTITALIC);
3789 		DiaUnDimItem(dia, DATR_TEXTBOLD);
3790 		DiaUnDimItem(dia, DATR_TEXTUNDERLINE);
3791 	} else
3792 	{
3793 		DiaDimItem(dia, DATR_TEXTITALIC);
3794 		DiaDimItem(dia, DATR_TEXTBOLD);
3795 		DiaDimItem(dia, DATR_TEXTUNDERLINE);
3796 	}
3797 	DiaSetControl(dia, DATR_NAMECENT, 1);
3798 	DiaSetControl(dia, DATR_RELTEXTSIZE_L, 1);
3799 	DiaSetText(dia, DATR_RELTEXTSIZE, x_("1"));
3800 
3801 	/* determine what attributes can be set */
3802 	us_attrnodeinstaddr = NONODEINST;
3803 	us_attrexportprotoaddr = NOPORTPROTO;
3804 	us_attrportprotoaddr = NOPORTPROTO;
3805 	us_attrarcinstaddr = NOARCINST;
3806 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
3807 	if (var != NOVARIABLE)
3808 	{
3809 		if (getlength(var) == 1)
3810 		{
3811 			if (!us_makehighlight(((CHAR **)var->addr)[0], &high))
3812 			{
3813 				if ((high.status&HIGHTYPE) == HIGHFROM)
3814 				{
3815 					if (!high.fromgeom->entryisnode)
3816 					{
3817 						us_attrarcinstaddr = high.fromgeom->entryaddr.ai;
3818 					} else
3819 					{
3820 						us_attrnodeinstaddr = high.fromgeom->entryaddr.ni;
3821 						if (high.fromport != NOPORTPROTO)
3822 						{
3823 							for(pe = us_attrnodeinstaddr->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
3824 								if (pe->proto == high.fromport) break;
3825 							if (pe != NOPORTEXPINST) us_attrexportprotoaddr = high.fromport;
3826 							if (us_attrnodeinstaddr->proto->primindex == 0) us_attrportprotoaddr = high.fromport;
3827 						}
3828 					}
3829 				} else if ((high.status&HIGHTYPE) == HIGHTEXT)
3830 				{
3831 					if (high.fromvar != NOVARIABLE)
3832 					{
3833 						if (high.fromgeom != NOGEOM)
3834 						{
3835 							if (high.fromgeom->entryisnode)
3836 							{
3837 								/* node variable */
3838 								us_attrnodeinstaddr = high.fromgeom->entryaddr.ni;
3839 								if (high.fromport != NOPORTPROTO)
3840 									us_attrexportprotoaddr = high.fromport;
3841 							} else
3842 							{
3843 								/* arc variable */
3844 								us_attrarcinstaddr = high.fromgeom->entryaddr.ai;
3845 							}
3846 						}
3847 					} else if (high.fromport != NOPORTPROTO)
3848 					{
3849 						us_attrexportprotoaddr = high.fromport;
3850 					}
3851 				}
3852 			}
3853 		}
3854 	}
3855 
3856 	/* load the button names and determine initial control */
3857 	infstr = initinfstr();
3858 	formatinfstr(infstr, _("Cell (%s)"), describenodeproto(us_attrnodeprotoaddr));
3859 	DiaSetText(dia, DATR_CELLATTRS, returninfstr(infstr));
3860 	curcontrol = DATR_CELLATTRS;
3861 	if (us_attrexportprotoaddr == NOPORTPROTO)
3862 		us_attrexportprotoaddr = us_attrnodeprotoaddr->firstportproto; else
3863 			curcontrol = DATR_EXPORTATTRS;
3864 	if (us_attrexportprotoaddr != NOPORTPROTO)
3865 	{
3866 		DiaUnDimItem(dia, DATR_EXPORTATTRS);
3867 		infstr = initinfstr();
3868 		formatinfstr(infstr, _("Cell Export (%s)"), us_attrexportprotoaddr->protoname);
3869 		DiaSetText(dia, DATR_EXPORTATTRS, returninfstr(infstr));
3870 	} else DiaDimItem(dia, DATR_EXPORTATTRS);
3871 	if (us_attrnodeinstaddr != NONODEINST)
3872 	{
3873 		DiaUnDimItem(dia, DATR_NODEATTRS);
3874 		infstr = initinfstr();
3875 		formatinfstr(infstr, _("Node (%s)"), describenodeinst(us_attrnodeinstaddr));
3876 		DiaSetText(dia, DATR_NODEATTRS, returninfstr(infstr));
3877 		curcontrol = DATR_NODEATTRS;
3878 	} else DiaDimItem(dia, DATR_NODEATTRS);
3879 	if (us_attrportprotoaddr != NOPORTPROTO)
3880 	{
3881 		DiaUnDimItem(dia, DATR_PORTATTRS);
3882 		infstr = initinfstr();
3883 		formatinfstr(infstr, _("Node Port (%s)"), us_attrportprotoaddr->protoname);
3884 		DiaSetText(dia, DATR_PORTATTRS, returninfstr(infstr));
3885 		curcontrol = DATR_PORTATTRS;
3886 	} else DiaDimItem(dia, DATR_PORTATTRS);
3887 	if (us_attrarcinstaddr != NOARCINST)
3888 	{
3889 		DiaUnDimItem(dia, DATR_ARCATTRS);
3890 		infstr = initinfstr();
3891 		formatinfstr(infstr, _("Network (%s)"), describearcinst(us_attrarcinstaddr));
3892 		DiaSetText(dia, DATR_ARCATTRS, returninfstr(infstr));
3893 		curcontrol = DATR_ARCATTRS;
3894 	} else DiaDimItem(dia, DATR_ARCATTRS);
3895 
3896 	DiaSetControl(dia, curcontrol, 1);
3897 	switch (curcontrol)
3898 	{
3899 		case DATR_CELLATTRS:   addr = (INTBIG)us_attrnodeprotoaddr;    type = VNODEPROTO;   break;
3900 		case DATR_NODEATTRS:   addr = (INTBIG)us_attrnodeinstaddr;     type = VNODEINST;    break;
3901 		case DATR_EXPORTATTRS: addr = (INTBIG)us_attrexportprotoaddr;  type = VPORTPROTO;   break;
3902 		case DATR_PORTATTRS:   addr = (INTBIG)us_attrnodeinstaddr;     type = VNODEINST;    break;
3903 		case DATR_ARCATTRS:    addr = (INTBIG)us_attrarcinstaddr;      type = VARCINST;     break;
3904 		default:               addr = 0;                               type = VUNKNOWN;     break;
3905 	}
3906 	if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_EXPORTATTRS)
3907 		DiaUnDimItem(dia, DATR_INHERIT); else
3908 	{
3909 		DiaSetControl(dia, DATR_INHERIT, 0);
3910 		DiaDimItem(dia, DATR_INHERIT);
3911 	}
3912 	if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_NODEATTRS)
3913 		DiaUnDimItem(dia, DATR_ISPARAMETER); else
3914 	{
3915 		DiaSetControl(dia, DATR_ISPARAMETER, 0);
3916 		DiaDimItem(dia, DATR_ISPARAMETER);
3917 	}
3918 	us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
3919 	us_attrloadchoices(numvar, firstvar, curcontrol, dia);
3920 	us_attrloadportlist(curcontrol, dia);
3921 
3922 	/* loop until done */
3923 	for(;;)
3924 	{
3925 		itemHit = DiaNextHit(dia);
3926 		if (itemHit == OK) break;
3927 		if (itemHit >= DATR_CELLATTRS && itemHit <= DATR_ARCATTRS)
3928 		{
3929 			/* selected different object */
3930 			for(i=DATR_CELLATTRS; i<=DATR_ARCATTRS; i++) DiaSetControl(dia, i, 0);
3931 			curcontrol = itemHit;
3932 			DiaSetControl(dia, curcontrol, 1);
3933 			switch (curcontrol)
3934 			{
3935 				case DATR_CELLATTRS:   addr = (INTBIG)us_attrnodeprotoaddr;    type = VNODEPROTO;   break;
3936 				case DATR_NODEATTRS:   addr = (INTBIG)us_attrnodeinstaddr;     type = VNODEINST;    break;
3937 				case DATR_EXPORTATTRS: addr = (INTBIG)us_attrexportprotoaddr;  type = VPORTPROTO;   break;
3938 				case DATR_PORTATTRS:   addr = (INTBIG)us_attrnodeinstaddr;     type = VNODEINST;    break;
3939 				case DATR_ARCATTRS:    addr = (INTBIG)us_attrarcinstaddr;      type = VARCINST;     break;
3940 				default:               addr = 0;                               type = VUNKNOWN;     break;
3941 			}
3942 			DiaSetText(dia, DATR_ATTRNAME, x_(""));
3943 			if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_EXPORTATTRS)
3944 				DiaUnDimItem(dia, DATR_INHERIT); else
3945 			{
3946 				DiaSetControl(dia, DATR_INHERIT, 0);
3947 				DiaDimItem(dia, DATR_INHERIT);
3948 			}
3949 			if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_NODEATTRS)
3950 				DiaUnDimItem(dia, DATR_ISPARAMETER); else
3951 			{
3952 				DiaSetControl(dia, DATR_ISPARAMETER, 0);
3953 				DiaDimItem(dia, DATR_ISPARAMETER);
3954 			}
3955 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
3956 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
3957 			us_attrloadportlist(curcontrol, dia);
3958 			DiaDefaultButton(dia, OK);
3959 			continue;
3960 		}
3961 		if (itemHit == DATR_ATTRLIST)
3962 		{
3963 			/* selected attribute name in scroll area */
3964 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
3965 			us_attrselectattributeline(curcontrol, i, numvar, firstvar, dia);
3966 			DiaDefaultButton(dia, OK);
3967 			continue;
3968 		}
3969 		if (itemHit == DATR_PORTLIST)
3970 		{
3971 			/* selected port name */
3972 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
3973 			if (i < 0) attrname = 0; else
3974 				(void)allocstring(&attrname, DiaGetScrollLine(dia, DATR_ATTRLIST, i), el_tempcluster);
3975 			which = DiaGetCurLine(dia, DATR_PORTLIST);
3976 			pt = DiaGetScrollLine(dia, DATR_PORTLIST, which);
3977 			if (*pt == '>') DiaDefaultButton(dia, DATR_REMOVEPORT); else
3978 				DiaDefaultButton(dia, DATR_ADDPORT);
3979 			if (curcontrol == DATR_EXPORTATTRS)
3980 			{
3981 				for(i=0, pp = us_attrnodeprotoaddr->firstportproto; pp != NOPORTPROTO;
3982 					pp = pp->nextportproto, i++)
3983 						if (which == i) break;
3984 				if (pp == NOPORTPROTO) continue;
3985 				us_attrexportprotoaddr = pp;
3986 				infstr = initinfstr();
3987 				formatinfstr(infstr, _("Cell Export (%s)"), us_attrexportprotoaddr->protoname);
3988 				DiaSetText(dia, DATR_EXPORTATTRS, returninfstr(infstr));
3989 				addr = (INTBIG)us_attrexportprotoaddr;
3990 			} else
3991 			{
3992 				for(i=0, pp = us_attrnodeinstaddr->proto->firstportproto; pp != NOPORTPROTO;
3993 					pp = pp->nextportproto, i++)
3994 						if (which == i) break;
3995 				if (pp == NOPORTPROTO) continue;
3996 				us_attrportprotoaddr = pp;
3997 				infstr = initinfstr();
3998 				formatinfstr(infstr, _("Node Port (%s)"), us_attrportprotoaddr->protoname);
3999 				DiaSetText(dia, DATR_PORTATTRS, returninfstr(infstr));
4000 			}
4001 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
4002 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
4003 
4004 			/* see if former attribute name is in the new list */
4005 			if (attrname != 0)
4006 			{
4007 				listlen = DiaGetNumScrollLines(dia, DATR_ATTRLIST);
4008 				for(i=0; i<listlen; i++)
4009 				{
4010 					pt = DiaGetScrollLine(dia, DATR_ATTRLIST, i);
4011 					if (namesame(pt, attrname) == 0)
4012 					{
4013 						DiaSelectLine(dia, DATR_ATTRLIST, i);
4014 						us_attrselectattributeline(curcontrol, i, numvar, firstvar, dia);
4015 						break;
4016 					}
4017 				}
4018 				efree(attrname);
4019 			}
4020 			continue;
4021 		}
4022 		if (itemHit >= DATR_FIRSTICON && itemHit <= DATR_LASTICON)
4023 		{
4024 			/* icon clicks: convert to buttons */
4025 			DiaGetMouse(dia, &x, &y);
4026 			DiaItemRect(dia, itemHit, &r);
4027 			i = (itemHit-DATR_FIRSTICON) * 2;
4028 			if (y > (r.top+r.bottom)/2) i++;
4029 			itemHit = i + DATR_FIRSTNAMEBUT;
4030 		}
4031 		if (itemHit >= DATR_FIRSTNAMEBUT && itemHit <= DATR_LASTNAMEBUT)
4032 		{
4033 			/* change text position */
4034 			for(i=DATR_FIRSTNAMEBUT; i<=DATR_LASTNAMEBUT; i++) DiaSetControl(dia, i, 0);
4035 			DiaSetControl(dia, itemHit, 1);
4036 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4037 			if (i < 0) continue;
4038 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4039 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4040 			if (var == NOVARIABLE) continue;
4041 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4042 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4043 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4044 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4045 			modifydescript(addr, type, var, descript);
4046 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4047 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4048 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4049 			us_endbatch();
4050 			DiaDefaultButton(dia, OK);
4051 			continue;
4052 		}
4053 		if (itemHit == DATR_XOFFSET || itemHit == DATR_YOFFSET)
4054 		{
4055 			/* change text offset */
4056 			if (curcontrol == DATR_PORTATTRS) continue;
4057 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4058 			if (i < 0) continue;
4059 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4060 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4061 			if (var == NOVARIABLE) continue;
4062 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4063 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4064 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4065 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4066 			modifydescript(addr, type, var, descript);
4067 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4068 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4069 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4070 			us_endbatch();
4071 			DiaDefaultButton(dia, OK);
4072 		}
4073 		if (itemHit == DATR_RELTEXTSIZE_L || itemHit == DATR_ABSTEXTSIZE_L)
4074 		{
4075 			/* change text size */
4076 			DiaSetControl(dia, DATR_RELTEXTSIZE_L, 0);
4077 			DiaSetControl(dia, DATR_ABSTEXTSIZE_L, 0);
4078 			DiaSetControl(dia, itemHit, 1);
4079 			if (itemHit == DATR_RELTEXTSIZE_L)
4080 			{
4081 				DiaUnDimItem(dia, DATR_RELTEXTSIZE);
4082 				DiaDimItem(dia, DATR_ABSTEXTSIZE);
4083 				itemHit = DATR_RELTEXTSIZE;
4084 			} else
4085 			{
4086 				DiaUnDimItem(dia, DATR_ABSTEXTSIZE);
4087 				DiaDimItem(dia, DATR_RELTEXTSIZE);
4088 				itemHit = DATR_ABSTEXTSIZE;
4089 			}
4090 		}
4091 		if (itemHit == DATR_RELTEXTSIZE || itemHit == DATR_ABSTEXTSIZE)
4092 		{
4093 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4094 			if (i < 0) continue;
4095 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4096 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4097 			if (var == NOVARIABLE) continue;
4098 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4099 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4100 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4101 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4102 			modifydescript(addr, type, var, descript);
4103 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4104 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4105 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4106 			us_endbatch();
4107 			DiaDefaultButton(dia, OK);
4108 			continue;
4109 		}
4110 		if (itemHit == DATR_TEXTITALIC || itemHit == DATR_TEXTBOLD ||
4111 			itemHit == DATR_TEXTUNDERLINE)
4112 		{
4113 			/* change text style */
4114 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
4115 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4116 			if (i < 0) continue;
4117 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4118 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4119 			if (var == NOVARIABLE) continue;
4120 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4121 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4122 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4123 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4124 			modifydescript(addr, type, var, descript);
4125 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4126 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4127 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4128 			us_endbatch();
4129 			DiaDefaultButton(dia, OK);
4130 			continue;
4131 		}
4132 		if (itemHit == DATR_ROTATION)
4133 		{
4134 			/* change text rotation */
4135 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4136 			if (i < 0) continue;
4137 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4138 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4139 			if (var == NOVARIABLE) continue;
4140 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4141 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4142 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4143 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4144 			modifydescript(addr, type, var, descript);
4145 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4146 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4147 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4148 			us_endbatch();
4149 			DiaDefaultButton(dia, OK);
4150 			continue;
4151 		}
4152 		if (itemHit == DATR_UNITS)
4153 		{
4154 			/* change units */
4155 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4156 			if (i < 0) continue;
4157 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4158 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4159 			if (var == NOVARIABLE) continue;
4160 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4161 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4162 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4163 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4164 			modifydescript(addr, type, var, descript);
4165 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4166 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4167 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4168 			us_endbatch();
4169 			DiaDefaultButton(dia, OK);
4170 			continue;
4171 		}
4172 		if (itemHit == DATR_TEXTFACE)
4173 		{
4174 			/* change text face */
4175 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4176 			if (i < 0) continue;
4177 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4178 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4179 			if (var == NOVARIABLE) continue;
4180 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4181 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4182 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4183 			us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4184 			modifydescript(addr, type, var, descript);
4185 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4186 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4187 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4188 			us_endbatch();
4189 			DiaDefaultButton(dia, OK);
4190 			continue;
4191 		}
4192 		if (itemHit == DATR_WHATTOSHOW)
4193 		{
4194 			/* selected "what to show" */
4195 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4196 			if (i < 0) continue;
4197 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4198 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4199 			if (var == NOVARIABLE) continue;
4200 			us_pushhighlight();
4201 			us_clearhighlightcount();
4202 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4203 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4204 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4205 			if (DiaGetPopupEntry(dia, DATR_WHATTOSHOW) == 0) var->type &= ~VDISPLAY; else
4206 			{
4207 				var->type |= VDISPLAY;
4208 				us_attrtextposition(curcontrol, var->textdescript, descript, dia);
4209 				modifydescript(addr, type, var, descript);
4210 			}
4211 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4212 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4213 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4214 			us_pophighlight(TRUE);
4215 			DiaDefaultButton(dia, OK);
4216 			us_endbatch();
4217 			continue;
4218 		}
4219 		if (itemHit == DATR_LANGUAGE)
4220 		{
4221 			/* selected evaluation option */
4222 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4223 			if (i < 0) continue;
4224 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4225 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4226 			if (var == NOVARIABLE) continue;
4227 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4228 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4229 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4230 			switch (DiaGetPopupEntry(dia, DATR_LANGUAGE))
4231 			{
4232 				case 0: var->type = (var->type & ~(VCODE1|VCODE2)) | 0;       break;
4233 				case 1: var->type = (var->type & ~(VCODE1|VCODE2)) | VTCL;    break;
4234 				case 2: var->type = (var->type & ~(VCODE1|VCODE2)) | VLISP;   break;
4235 				case 3: var->type = (var->type & ~(VCODE1|VCODE2)) | VJAVA;   break;
4236 			}
4237 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4238 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4239 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4240 			us_endbatch();
4241 			us_attrselectattributeline(curcontrol, i, numvar, firstvar, dia);
4242 			DiaDefaultButton(dia, OK);
4243 			continue;
4244 		}
4245 		if (itemHit == DATR_INHERIT)
4246 		{
4247 			/* checked "instances inherit" */
4248 			value = 1 - DiaGetControl(dia, DATR_INHERIT);
4249 			DiaSetControl(dia, DATR_INHERIT, value);
4250 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4251 			if (i < 0) continue;
4252 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4253 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4254 			if (var == NOVARIABLE) continue;
4255 			TDCOPY(descript, var->textdescript);
4256 			if (value == 0) TDSETINHERIT(descript, 0); else
4257 				TDSETINHERIT(descript, VTINHERIT);
4258 			startobjectchange(addr, type);
4259 			modifydescript(addr, type, var, descript);
4260 			endobjectchange(addr, type);
4261 			DiaDefaultButton(dia, OK);
4262 			continue;
4263 		}
4264 		if (itemHit == DATR_ISPARAMETER)
4265 		{
4266 			/* checked "is parameter" */
4267 			value = 1 - DiaGetControl(dia, DATR_ISPARAMETER);
4268 			DiaSetControl(dia, DATR_ISPARAMETER, value);
4269 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4270 			if (i < 0) continue;
4271 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0) continue;
4272 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4273 			if (var == NOVARIABLE) continue;
4274 			TDCOPY(descript, var->textdescript);
4275 			if (value == 0) TDSETISPARAM(descript, 0); else
4276 				TDSETISPARAM(descript, VTISPARAMETER);
4277 			startobjectchange(addr, type);
4278 			modifydescript(addr, type, var, descript);
4279 			endobjectchange(addr, type);
4280 			DiaDefaultButton(dia, OK);
4281 			continue;
4282 		}
4283 		if (itemHit == DATR_CHANGEATTR)
4284 		{
4285 			/* change attribute value */
4286 			i = DiaGetCurLine(dia, DATR_ATTRLIST);
4287 			if (i < 0) continue;
4288 			if (namesame(DiaGetScrollLine(dia, DATR_ATTRLIST, i), DiaGetText(dia, DATR_ATTRNAME)) != 0)
4289 			{
4290 				ttybeep(SOUNDBEEP, TRUE);
4291 				continue;
4292 			}
4293 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4294 			if (var == NOVARIABLE) continue;
4295 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4296 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4297 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4298 			pt = DiaGetText(dia, DATR_ATTRVALUE);
4299 			TDCOPY(descript, var->textdescript);
4300 			if ((var->type&(VCODE1|VCODE2)) != 0)
4301 			{
4302 				newtype = var->type;
4303 				newaddr = (INTBIG)pt;
4304 			} else
4305 			{
4306 				getsimpletype(pt, &newtype, &newaddr, 0);
4307 				newtype |= var->type&VDISPLAY;
4308 			}
4309 			newvar = setvalkey(addr, type, var->key, newaddr, newtype);
4310 			if (newvar != NOVARIABLE)
4311 			{
4312 				TDCOPY(newvar->textdescript, descript);
4313 				if (curcontrol == DATR_CELLATTRS)
4314 					us_drawcellvariable(newvar, us_attrnodeprotoaddr);
4315 			}
4316 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4317 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4318 			us_endbatch();
4319 			us_attrselectattributeline(curcontrol, i, numvar, firstvar, dia);
4320 			DiaDefaultButton(dia, OK);
4321 			continue;
4322 		}
4323 		if (itemHit == DATR_RENAMEATTR)
4324 		{
4325 			/* rename attribute */
4326 			pt = DiaGetText(dia, DATR_ATTRNAME);
4327 			while (*pt == ' ' || *pt == '\t') pt++;
4328 			if (*pt == 0)
4329 			{
4330 				DiaMessageInDialog(_("No attribute name given"));
4331 				continue;
4332 			}
4333 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4334 			if (var == NOVARIABLE) continue;
4335 			(void)allocstring(&newvarname, us_attrmakevarname(curcontrol, us_attrportprotoaddr, pt), el_tempcluster);
4336 			pt = DiaGetText(dia, DATR_ATTRVALUE);
4337 			newtype = var->type;
4338 			TDCOPY(descript, var->textdescript);
4339 			startobjectchange(addr, type);
4340 			if (curcontrol == DATR_CELLATTRS) us_undrawcellvariable(var, us_attrnodeprotoaddr);
4341 			(void)delvalkey(addr, type, var->key);
4342 			if ((newtype&VTYPE) == VSTRING || (newtype&(VCODE1|VCODE2)) != 0)
4343 			{
4344 				newvar = setval(addr, type, newvarname, (INTBIG)pt, newtype);
4345 			} else switch (newtype&VTYPE)
4346 			{
4347 				case VINTEGER:
4348 					newvar = setval(addr, type, newvarname, eatoi(pt), newtype);
4349 					break;
4350 				case VFLOAT:
4351 					newvar = setval(addr, type, newvarname, castint((float)eatof(pt)),
4352 						newtype);
4353 					break;
4354 				default:
4355 					newvar = NOVARIABLE;
4356 					break;
4357 			}
4358 			efree(newvarname);
4359 			if (newvar != NOVARIABLE)
4360 			{
4361 				TDCOPY(newvar->textdescript, descript);
4362 				if (curcontrol == DATR_CELLATTRS)
4363 					us_drawcellvariable(newvar, us_attrnodeprotoaddr);
4364 			}
4365 			endobjectchange(addr, type);
4366 			us_endbatch();
4367 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
4368 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
4369 			DiaDefaultButton(dia, OK);
4370 			continue;
4371 		}
4372 		if (itemHit == DATR_DELETEATTR)
4373 		{
4374 			/* delete attribute */
4375 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4376 			if (var == NOVARIABLE) continue;
4377 			if (curcontrol != DATR_EXPORTATTRS) startobjectchange(addr, type); else
4378 				startobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4379 			if (curcontrol == DATR_CELLATTRS) us_drawcellvariable(var, us_attrnodeprotoaddr);
4380 			(void)delvalkey(addr, type, var->key);
4381 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4382 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4383 			us_endbatch();
4384 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
4385 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
4386 			DiaDefaultButton(dia, OK);
4387 			continue;
4388 		}
4389 		if (itemHit == DATR_CREATEATTR)
4390 		{
4391 			/* new attribute */
4392 			pt = DiaGetText(dia, DATR_ATTRNAME);
4393 			while (*pt == ' ' || *pt == '\t') pt++;
4394 			if (*pt == 0)
4395 			{
4396 				DiaMessageInDialog(_("No attribute name given"));
4397 				continue;
4398 			}
4399 			(void)allocstring(&newvarname, us_attrmakevarname(curcontrol, us_attrportprotoaddr, pt), el_tempcluster);
4400 			pt = DiaGetText(dia, DATR_ATTRVALUE);
4401 			getsimpletype(pt, &newtype, &newval, 0);
4402 			if (DiaGetPopupEntry(dia, DATR_WHATTOSHOW) != 0) newtype |= VDISPLAY;
4403 			switch (DiaGetPopupEntry(dia, DATR_LANGUAGE))
4404 			{
4405 				case 1: newtype |= VTCL;    break;
4406 				case 2: newtype |= VLISP;   break;
4407 				case 3: newtype |= VJAVA;   break;
4408 			}
4409 			startobjectchange(addr, type);
4410 			newvar = setval(addr, type, newvarname, newval, newtype);
4411 			efree(newvarname);
4412 			if (newvar != NOVARIABLE)
4413 			{
4414 				if (curcontrol == DATR_PORTATTRS)
4415 				{
4416 					/* add in offset to the port */
4417 					us_attrsetportposition(newvar, us_attrportprotoaddr);
4418 				}
4419 				us_attrtextposition(curcontrol, newvar->textdescript, newvar->textdescript, dia);
4420 				if (curcontrol == DATR_CELLATTRS)
4421 					us_drawcellvariable(newvar, us_attrnodeprotoaddr);
4422 			}
4423 			if (curcontrol != DATR_EXPORTATTRS) endobjectchange(addr, type); else
4424 				endobjectchange((INTBIG)us_attrexportprotoaddr->subnodeinst, VNODEINST);
4425 			us_endbatch();
4426 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
4427 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
4428 			DiaDefaultButton(dia, OK);
4429 			continue;
4430 		}
4431 		if (itemHit == DATR_ADDPORT)
4432 		{
4433 			/* Add port to array */
4434 			i = DiaGetCurLine(dia, DATR_PORTLIST);
4435 			if (i < 0) continue;
4436 			pt = DiaGetScrollLine(dia, DATR_PORTLIST, i);
4437 			if (pt[0] == '>' && pt[1] == ' ') continue;
4438 			infstr = initinfstr();
4439 			addstringtoinfstr(infstr, x_("> "));
4440 			addstringtoinfstr(infstr, pt);
4441 			DiaSetScrollLine(dia, DATR_PORTLIST, i, returninfstr(infstr));
4442 			DiaDefaultButton(dia, OK);
4443 			continue;
4444 		}
4445 		if (itemHit == DATR_REMOVEPORT)
4446 		{
4447 			/* Remove port from array */
4448 			i = DiaGetCurLine(dia, DATR_PORTLIST);
4449 			if (i < 0) continue;
4450 			pt = DiaGetScrollLine(dia, DATR_PORTLIST, i);
4451 			if (pt[0] != '>' || pt[1] != ' ') continue;
4452 			DiaSetScrollLine(dia, DATR_PORTLIST, i, &pt[2]);
4453 			DiaDefaultButton(dia, OK);
4454 			continue;
4455 		}
4456 		if (itemHit == DATR_ADDALLPORTS)
4457 		{
4458 			/* Add all ports to array */
4459 			which = DiaGetCurLine(dia, DATR_PORTLIST);
4460 			listlen = DiaGetNumScrollLines(dia, DATR_PORTLIST);
4461 			for(i=0; i<listlen; i++)
4462 			{
4463 				pt = DiaGetScrollLine(dia, DATR_PORTLIST, i);
4464 				if (pt[0] == '>' && pt[1] == ' ') continue;
4465 				infstr = initinfstr();
4466 				addstringtoinfstr(infstr, x_("> "));
4467 				addstringtoinfstr(infstr, pt);
4468 				DiaSetScrollLine(dia, DATR_PORTLIST, i, returninfstr(infstr));
4469 			}
4470 			DiaSelectLine(dia, DATR_PORTLIST, which);
4471 			DiaDefaultButton(dia, OK);
4472 			continue;
4473 		}
4474 		if (itemHit == DATR_REMOVEALLPORTS)
4475 		{
4476 			/* Remove all ports from array */
4477 			which = DiaGetCurLine(dia, DATR_PORTLIST);
4478 			listlen = DiaGetNumScrollLines(dia, DATR_PORTLIST);
4479 			for(i=0; i<listlen; i++)
4480 			{
4481 				pt = DiaGetScrollLine(dia, DATR_PORTLIST, i);
4482 				if (pt[0] != '>' || pt[1] != ' ') continue;
4483 				DiaSetScrollLine(dia, DATR_PORTLIST, i, &pt[2]);
4484 			}
4485 			DiaSelectLine(dia, DATR_PORTLIST, which);
4486 			DiaDefaultButton(dia, OK);
4487 			continue;
4488 		}
4489 		if (itemHit == DATR_ARRAYPORT)
4490 		{
4491 			/* "Make Array" button: array port or export attribute */
4492 			var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4493 			if (var == NOVARIABLE) continue;
4494 			(void)allocstring(&attrname, DiaGetScrollLine(dia, DATR_ATTRLIST, DiaGetCurLine(dia, DATR_ATTRLIST)),
4495 				el_tempcluster);
4496 			switch (var->type&VTYPE)
4497 			{
4498 				case VINTEGER:
4499 					esnprintf(line, 50, x_("%ld"), var->addr);
4500 					(void)allocstring(&oldvalue, line, el_tempcluster);
4501 					break;
4502 				case VFLOAT:
4503 					esnprintf(line, 50, x_("%g"), castfloat(var->addr));
4504 					(void)allocstring(&oldvalue, line, el_tempcluster);
4505 					break;
4506 				case VSTRING:
4507 					(void)allocstring(&oldvalue, (CHAR *)var->addr, el_tempcluster);
4508 					break;
4509 			}
4510 			newtype = var->type;
4511 			if (curcontrol == DATR_EXPORTATTRS) proto = us_attrnodeprotoaddr; else
4512 			{
4513 				proto = us_attrnodeinstaddr->proto;
4514 				startobjectchange(addr, type);
4515 			}
4516 			for(i=0, pp = proto->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto, i++)
4517 			{
4518 				pt = DiaGetScrollLine(dia, DATR_PORTLIST, i);
4519 				if (pt[0] != '>' || pt[1] != ' ') continue;
4520 				(void)allocstring(&newvarname, us_attrmakevarname(curcontrol, pp, attrname),
4521 					el_tempcluster);
4522 				if (curcontrol == DATR_EXPORTATTRS)
4523 				{
4524 					tempaddr = (INTBIG)pp;    temptype = VPORTPROTO;
4525 				} else
4526 				{
4527 					tempaddr = addr;   temptype = type;
4528 				}
4529 				newvar = getval(tempaddr, temptype, -1, newvarname);
4530 				if (newvar == NOVARIABLE)
4531 				{
4532 					if (curcontrol == DATR_EXPORTATTRS)
4533 						startobjectchange((INTBIG)pp->subnodeinst, VNODEINST);
4534 					newvalue = us_attrgenportvalue(curcontrol, addr, type, attrname,
4535 						proto, oldvalue);
4536 					switch (newtype&VTYPE)
4537 					{
4538 						case VINTEGER:
4539 							newvar = setval(tempaddr, temptype, newvarname,
4540 								eatoi(newvalue), newtype);
4541 							break;
4542 						case VFLOAT:
4543 							newvar = setval(tempaddr, temptype, newvarname,
4544 								castint((float)eatof(newvalue)), newtype);
4545 							break;
4546 						case VSTRING:
4547 							newvar = setval(tempaddr, temptype, newvarname,
4548 								(INTBIG)newvalue, newtype);
4549 							break;
4550 						default:
4551 							newvar = NOVARIABLE;
4552 							break;
4553 					}
4554 					if (newvar != NOVARIABLE)
4555 					{
4556 						if (curcontrol == DATR_PORTATTRS)
4557 							us_attrsetportposition(newvar, pp);
4558 						us_attrtextposition(curcontrol, newvar->textdescript, newvar->textdescript, dia);
4559 					}
4560 					if (curcontrol == DATR_EXPORTATTRS)
4561 						endobjectchange((INTBIG)pp->subnodeinst, VNODEINST);
4562 				}
4563 				efree(newvarname);
4564 			}
4565 			if (curcontrol == DATR_PORTATTRS) endobjectchange(addr, type);
4566 			us_endbatch();
4567 			efree(oldvalue);
4568 			efree(attrname);
4569 			us_attrgetfactors(curcontrol, addr, &numvar, &firstvar);
4570 			us_attrloadchoices(numvar, firstvar, curcontrol, dia);
4571 			DiaDefaultButton(dia, OK);
4572 			continue;
4573 		}
4574 	}
4575 	DiaDoneDialog(dia);
4576 	return(0);
4577 }
4578 
4579 /* helper routine to modify the text descriptor from the dialog controls */
us_attrtextposition(INTBIG curcontrol,UINTBIG * olddescript,UINTBIG * newdescript,void * dia)4580 void us_attrtextposition(INTBIG curcontrol, UINTBIG *olddescript, UINTBIG *newdescript, void *dia)
4581 {
4582 	INTBIG value, x, y;
4583 
4584 	TDCOPY(newdescript, olddescript);
4585 	if (DiaGetControl(dia, DATR_NAMECENT) != 0) TDSETPOS(newdescript, VTPOSCENT);
4586 	if (DiaGetControl(dia, DATR_NAMEBOT) != 0) TDSETPOS(newdescript, VTPOSUP);
4587 	if (DiaGetControl(dia, DATR_NAMETOP) != 0) TDSETPOS(newdescript, VTPOSDOWN);
4588 	if (DiaGetControl(dia, DATR_NAMERIGHT) != 0) TDSETPOS(newdescript, VTPOSLEFT);
4589 	if (DiaGetControl(dia, DATR_NAMELEFT) != 0) TDSETPOS(newdescript, VTPOSRIGHT);
4590 	if (DiaGetControl(dia, DATR_NAMELOWRIGHT) != 0) TDSETPOS(newdescript, VTPOSUPLEFT);
4591 	if (DiaGetControl(dia, DATR_NAMELOWLEFT) != 0) TDSETPOS(newdescript, VTPOSUPRIGHT);
4592 	if (DiaGetControl(dia, DATR_NAMEUPRIGHT) != 0) TDSETPOS(newdescript, VTPOSDOWNLEFT);
4593 	if (DiaGetControl(dia, DATR_NAMEUPLEFT) != 0) TDSETPOS(newdescript, VTPOSDOWNRIGHT);
4594 
4595 	if (DiaGetControl(dia, DATR_ABSTEXTSIZE_L) != 0)
4596 	{
4597 		value = eatoi(DiaGetText(dia, DATR_ABSTEXTSIZE));
4598 		if (value <= 0) value = 4;
4599 		if (value >= TXTMAXPOINTS) value = TXTMAXPOINTS;
4600 		TDSETSIZE(newdescript, TXTSETPOINTS(value));
4601 	} else
4602 	{
4603 		value = atofr(DiaGetText(dia, DATR_RELTEXTSIZE)) * 4 / WHOLE;
4604 		if (value <= 0) value = 4;
4605 		if (value >= TXTMAXQLAMBDA) value = TXTMAXQLAMBDA;
4606 		TDSETSIZE(newdescript, TXTSETQLAMBDA(value));
4607 	}
4608 	if (DiaGetControl(dia, DATR_TEXTITALIC) != 0)
4609 		TDSETITALIC(newdescript, VTITALIC); else
4610 			TDSETITALIC(newdescript, 0);
4611 	if (DiaGetControl(dia, DATR_TEXTBOLD) != 0)
4612 		TDSETBOLD(newdescript, VTBOLD); else
4613 			TDSETBOLD(newdescript, 0);
4614 	if (DiaGetControl(dia, DATR_TEXTUNDERLINE) != 0)
4615 		TDSETUNDERLINE(newdescript, VTUNDERLINE); else
4616 			TDSETUNDERLINE(newdescript, 0);
4617 	if (graphicshas(CANCHOOSEFACES))
4618 	{
4619 		value = us_getpopupface(DATR_TEXTFACE, dia);
4620 		TDSETFACE(newdescript, value);
4621 	}
4622 	value = DiaGetPopupEntry(dia, DATR_UNITS);
4623 	TDSETUNITS(newdescript, value);
4624 	value = DiaGetPopupEntry(dia, DATR_ROTATION);
4625 	TDSETROTATION(newdescript, value);
4626 	value = DiaGetPopupEntry(dia, DATR_WHATTOSHOW);
4627 	switch (value)
4628 	{
4629 		case 1: TDSETDISPPART(newdescript, VTDISPLAYVALUE);          break;
4630 		case 2: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALUE);      break;
4631 		case 3: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALINH);     break;
4632 		case 4: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALINHALL);  break;
4633 	}
4634 	if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_EXPORTATTRS)
4635 	{
4636 		TDSETINHERIT(newdescript, 0);
4637 		if (DiaGetControl(dia, DATR_INHERIT) != 0) TDSETINHERIT(newdescript, VTINHERIT);
4638 	}
4639 	if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_NODEATTRS)
4640 	{
4641 		TDSETISPARAM(newdescript, 0);
4642 		if (DiaGetControl(dia, DATR_ISPARAMETER) != 0) TDSETISPARAM(newdescript, VTISPARAMETER);
4643 	}
4644 	if (curcontrol != DATR_PORTATTRS)
4645 	{
4646 		x = atofr(DiaGetText(dia, DATR_XOFFSET)) * 4 / WHOLE;
4647 		y = atofr(DiaGetText(dia, DATR_YOFFSET)) * 4 / WHOLE;
4648 		TDSETOFF(newdescript, x, y);
4649 	}
4650 }
4651 
us_attrselectattributeline(INTBIG curcontrol,INTBIG which,INTBIG numvar,VARIABLE * firstvar,void * dia)4652 void us_attrselectattributeline(INTBIG curcontrol, INTBIG which, INTBIG numvar, VARIABLE *firstvar, void *dia)
4653 {
4654 	REGISTER VARIABLE *var, *evar;
4655 	REGISTER INTBIG x, y, i, lambda, height;
4656 	UINTBIG savedescript[TEXTDESCRIPTSIZE];
4657 	CHAR buf[30];
4658 	REGISTER void *infstr;
4659 
4660 	if (which < 0) return;
4661 	var = us_attrfindvarname(curcontrol, numvar, firstvar, dia);
4662 	if (var == NOVARIABLE) return;
4663 	DiaSetText(dia, DATR_ATTRNAME, DiaGetScrollLine(dia, DATR_ATTRLIST, which));
4664 
4665 	/* make sure that only the value is described */
4666 	TDCOPY(savedescript, var->textdescript);
4667 	TDSETDISPPART(var->textdescript, 0);
4668 
4669 	/* find lambda */
4670 	switch (curcontrol)
4671 	{
4672 		case DATR_CELLATTRS:
4673 			lambda = el_curlib->lambda[us_attrnodeprotoaddr->tech->techindex];
4674 			break;
4675 		case DATR_NODEATTRS:
4676 			lambda = figurelambda(us_attrnodeinstaddr->geom);
4677 			break;
4678 		case DATR_EXPORTATTRS:
4679 			lambda = el_curlib->lambda[us_attrexportprotoaddr->parent->tech->techindex];
4680 			break;
4681 		case DATR_ARCATTRS:
4682 			lambda = figurelambda(us_attrarcinstaddr->geom);
4683 			break;
4684 		default:
4685 			lambda = 0;
4686 			break;
4687 	}
4688 
4689 	/* get the value */
4690 	if ((var->type&VISARRAY) != 0)
4691 	{
4692 		DiaSetText(dia, DATR_ATTRVALUE, describevariable(var, -1, 0));
4693 		DiaDimItem(dia, DATR_ATTRVALUE);
4694 	} else
4695 	{
4696 		DiaUnDimItem(dia, DATR_ATTRVALUE);
4697 		if ((var->type&VTYPE) == VSTRING) DiaSetText(dia, DATR_ATTRVALUE, (CHAR *)var->addr); else
4698 			DiaSetText(dia, DATR_ATTRVALUE, describevariable(var, -1, 0));
4699 	}
4700 	if ((var->type&(VCODE1|VCODE2)) == 0) DiaSetText(dia, DATR_EVALUATION, x_("")); else
4701 	{
4702 		switch (curcontrol)
4703 		{
4704 			case DATR_CELLATTRS:   evar = evalvar(var, (INTBIG)us_attrnodeprotoaddr, VNODEPROTO);   break;
4705 			case DATR_NODEATTRS:   evar = evalvar(var, (INTBIG)us_attrnodeinstaddr, VNODEINST);     break;
4706 			case DATR_EXPORTATTRS: evar = evalvar(var, (INTBIG)us_attrexportprotoaddr, VPORTPROTO); break;
4707 			case DATR_PORTATTRS:   evar = evalvar(var, (INTBIG)us_attrnodeinstaddr, VNODEINST);     break;
4708 			case DATR_ARCATTRS:    evar = evalvar(var, (INTBIG)us_attrarcinstaddr, VARCINST);       break;
4709 			default: evar = NOVARIABLE;
4710 		}
4711 		infstr = initinfstr();
4712 		addstringtoinfstr(infstr, _("Evaluation: "));
4713 		if ((evar->type&VTYPE) == VSTRING) addstringtoinfstr(infstr, (CHAR *)evar->addr); else
4714 			addstringtoinfstr(infstr, describevariable(evar, -1, 0));
4715 		DiaSetText(dia, DATR_EVALUATION, returninfstr(infstr));
4716 	}
4717 
4718 	/* restore the description information */
4719 	TDCOPY(var->textdescript, savedescript);
4720 
4721 	if ((var->type&VDISPLAY) == 0) DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 0); else
4722 	{
4723 		switch (TDGETDISPPART(var->textdescript))
4724 		{
4725 			case VTDISPLAYVALUE:         DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 1);   break;
4726 			case VTDISPLAYNAMEVALUE:     DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 2);   break;
4727 			case VTDISPLAYNAMEVALINH:    DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 3);   break;
4728 			case VTDISPLAYNAMEVALINHALL: DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 4);   break;
4729 		}
4730 	}
4731 	switch (var->type&(VCODE1|VCODE2))
4732 	{
4733 		case 0:     DiaSetPopupEntry(dia, DATR_LANGUAGE, 0);   break;
4734 		case VTCL:  DiaSetPopupEntry(dia, DATR_LANGUAGE, 1);   break;
4735 		case VLISP: DiaSetPopupEntry(dia, DATR_LANGUAGE, 2);   break;
4736 		case VJAVA: DiaSetPopupEntry(dia, DATR_LANGUAGE, 3);   break;
4737 	}
4738 	if (TDGETINHERIT(var->textdescript) != 0) DiaSetControl(dia, DATR_INHERIT, 1); else
4739 		DiaSetControl(dia, DATR_INHERIT, 0);
4740 	if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_NODEATTRS)
4741 	{
4742 		if (TDGETISPARAM(var->textdescript) != 0) DiaSetControl(dia, DATR_ISPARAMETER, 1); else
4743 			DiaSetControl(dia, DATR_ISPARAMETER, 0);
4744 	}
4745 	if (curcontrol == DATR_PORTATTRS)
4746 	{
4747 		DiaSetText(dia, DATR_XOFFSET, x_("0"));
4748 		DiaSetText(dia, DATR_YOFFSET, x_("0"));
4749 		DiaDimItem(dia, DATR_XOFFSET);
4750 		DiaDimItem(dia, DATR_YOFFSET);
4751 	} else
4752 	{
4753 		DiaUnDimItem(dia, DATR_XOFFSET);
4754 		DiaUnDimItem(dia, DATR_YOFFSET);
4755 		x = TDGETXOFF(var->textdescript);
4756 		x = x * WHOLE / 4;
4757 		y = TDGETYOFF(var->textdescript);
4758 		y = y * WHOLE / 4;
4759 		DiaSetText(dia, DATR_XOFFSET, frtoa(x));
4760 		DiaSetText(dia, DATR_YOFFSET, frtoa(y));
4761 	}
4762 	i = TDGETSIZE(var->textdescript);
4763 	if (TXTGETPOINTS(i) != 0)
4764 	{
4765 		/* show point size */
4766 		height = TXTGETPOINTS(i);
4767 		DiaUnDimItem(dia, DATR_ABSTEXTSIZE);
4768 		esnprintf(buf, 30, x_("%ld"), height);
4769 		DiaSetText(dia, DATR_ABSTEXTSIZE, buf);
4770 		DiaSetControl(dia, DATR_ABSTEXTSIZE_L, 1);
4771 
4772 		/* figure out how many lambda the point value is */
4773 		if (el_curwindowpart != NOWINDOWPART)
4774 			height = roundfloat((float)height / el_curwindowpart->scaley);
4775 		height = height * 4 / lambda;
4776 		DiaSetText(dia, DATR_RELTEXTSIZE, frtoa(height * WHOLE / 4));
4777 		DiaDimItem(dia, DATR_RELTEXTSIZE);
4778 		DiaSetControl(dia, DATR_RELTEXTSIZE_L, 0);
4779 	} else if (TXTGETQLAMBDA(i) != 0)
4780 	{
4781 		/* show lambda value */
4782 		height = TXTGETQLAMBDA(i);
4783 		DiaUnDimItem(dia, DATR_RELTEXTSIZE);
4784 		DiaSetText(dia, DATR_RELTEXTSIZE, frtoa(height * WHOLE / 4));
4785 		DiaSetControl(dia, DATR_RELTEXTSIZE_L, 1);
4786 		/* figure out how many points the lambda value is */
4787 		height = height * lambda / 4;
4788 		if (el_curwindowpart != NOWINDOWPART)
4789 			height = applyyscale(el_curwindowpart, height);
4790 		esnprintf(buf, 30, x_("%ld"), height);
4791 		DiaSetText(dia, DATR_ABSTEXTSIZE, buf);
4792 		DiaDimItem(dia, DATR_ABSTEXTSIZE);
4793 		DiaSetControl(dia, DATR_ABSTEXTSIZE_L, 0);
4794 	}
4795 	us_setpopupface(DATR_TEXTFACE, TDGETFACE(var->textdescript), FALSE, dia);
4796 	i = TDGETROTATION(var->textdescript);
4797 	DiaSetPopupEntry(dia, DATR_ROTATION, i);
4798 	i = TDGETUNITS(var->textdescript);
4799 	DiaSetPopupEntry(dia, DATR_UNITS, i);
4800 	if (graphicshas(CANMODIFYFONTS))
4801 	{
4802 		if (TDGETITALIC(var->textdescript) != 0) DiaSetControl(dia, DATR_TEXTITALIC, 1);
4803 		if (TDGETBOLD(var->textdescript) != 0) DiaSetControl(dia, DATR_TEXTBOLD, 1);
4804 		if (TDGETUNDERLINE(var->textdescript) != 0) DiaSetControl(dia, DATR_TEXTUNDERLINE, 1);
4805 	}
4806 	for(i=DATR_FIRSTNAMEBUT; i<=DATR_LASTNAMEBUT; i++) DiaSetControl(dia, i, 0);
4807 	switch (TDGETPOS(var->textdescript))
4808 	{
4809 		case VTPOSCENT:      DiaSetControl(dia, DATR_NAMECENT, 1);      break;
4810 		case VTPOSUP:        DiaSetControl(dia, DATR_NAMEBOT, 1);       break;
4811 		case VTPOSDOWN:      DiaSetControl(dia, DATR_NAMETOP, 1);       break;
4812 		case VTPOSLEFT:      DiaSetControl(dia, DATR_NAMERIGHT, 1);     break;
4813 		case VTPOSRIGHT:     DiaSetControl(dia, DATR_NAMELEFT, 1);      break;
4814 		case VTPOSUPLEFT:    DiaSetControl(dia, DATR_NAMELOWRIGHT, 1);  break;
4815 		case VTPOSUPRIGHT:   DiaSetControl(dia, DATR_NAMELOWLEFT, 1);   break;
4816 		case VTPOSDOWNLEFT:  DiaSetControl(dia, DATR_NAMEUPRIGHT, 1);   break;
4817 		case VTPOSDOWNRIGHT: DiaSetControl(dia, DATR_NAMEUPLEFT, 1);    break;
4818 	}
4819 }
4820 
us_attrsetportposition(VARIABLE * var,PORTPROTO * pp)4821 void us_attrsetportposition(VARIABLE *var, PORTPROTO *pp)
4822 {
4823 	INTBIG x, y;
4824 	REGISTER INTBIG lambda;
4825 
4826 	portposition(us_attrnodeinstaddr, pp, &x, &y);
4827 	x -= (us_attrnodeinstaddr->lowx + us_attrnodeinstaddr->highx) / 2;
4828 	y -= (us_attrnodeinstaddr->lowy + us_attrnodeinstaddr->highy) / 2;
4829 	lambda = figurelambda(us_attrnodeinstaddr->geom);
4830 	x = x * 4 / lambda;
4831 	y = y * 4 / lambda;
4832 	TDSETOFF(var->textdescript, x, y);
4833 }
4834 
us_attrgenportvalue(INTBIG curcontrol,INTBIG addr,INTBIG type,CHAR * attrname,NODEPROTO * np,CHAR * oldvalue)4835 CHAR *us_attrgenportvalue(INTBIG curcontrol, INTBIG addr, INTBIG type, CHAR *attrname, NODEPROTO *np,
4836 	CHAR *oldvalue)
4837 {
4838 	REGISTER PORTPROTO *pp;
4839 	REGISTER CHAR *pt, *start, save, *varname;
4840 	REGISTER VARIABLE *var;
4841 	CHAR line[50], *testvalue, *thisvalue;
4842 	REGISTER INTBIG value, i;
4843 	REGISTER void *infstr;
4844 
4845 	/* see if there are numbers here */
4846 	for(pt = oldvalue; *pt != 0; pt++)
4847 		if (isdigit(*pt) != 0) break;
4848 	if (*pt == 0) return(oldvalue);
4849 
4850 	/* get the number and the text around it */
4851 	start = pt;
4852 	while (isdigit(*pt) != 0) pt++;
4853 	value = eatoi(start);
4854 
4855 	/* loop through higher numbers looking for unused value */
4856 	for(i = value+1; i<value+5000; i++)
4857 	{
4858 		infstr = initinfstr();
4859 		save = *start;   *start = 0;
4860 		addstringtoinfstr(infstr, oldvalue);
4861 		*start = save;
4862 		esnprintf(line, 50, x_("%ld"), i);
4863 		addstringtoinfstr(infstr, line);
4864 		addstringtoinfstr(infstr, pt);
4865 		(void)allocstring(&testvalue, returninfstr(infstr), el_tempcluster);
4866 
4867 		/* see if the value is used */
4868 		for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
4869 		{
4870 			varname = us_attrmakevarname(curcontrol, pp, attrname);
4871 			if (curcontrol == DATR_PORTATTRS)
4872 			{
4873 				var = getval(addr, type, -1, varname);
4874 			} else
4875 			{
4876 				var = getval((INTBIG)pp, VPORTPROTO, -1, varname);
4877 			}
4878 			if (var == NOVARIABLE) continue;
4879 			switch (var->type&VTYPE)
4880 			{
4881 				case VINTEGER:
4882 					esnprintf(line, 50, x_("%ld"), var->addr);
4883 					thisvalue = line;
4884 					break;
4885 				case VFLOAT:
4886 					esnprintf(line, 50, x_("%g"), castfloat(var->addr));
4887 					thisvalue = line;
4888 					break;
4889 				case VSTRING:
4890 					thisvalue = (CHAR *)var->addr;
4891 					break;
4892 			}
4893 			if (namesame(thisvalue, testvalue) == 0) break;
4894 		}
4895 		if (pp == NOPORTPROTO)
4896 		{
4897 			infstr = initinfstr();
4898 			addstringtoinfstr(infstr, testvalue);
4899 			efree(testvalue);
4900 			return(returninfstr(infstr));
4901 		} else
4902 		{
4903 			efree(testvalue);
4904 		}
4905 	}
4906 	return(oldvalue);
4907 }
4908 
us_attrmakevarname(INTBIG curcontrol,PORTPROTO * pp,CHAR * name)4909 CHAR *us_attrmakevarname(INTBIG curcontrol, PORTPROTO *pp, CHAR *name)
4910 {
4911 	REGISTER void *infstr;
4912 
4913 	infstr = initinfstr();
4914 	if (curcontrol == DATR_PORTATTRS)
4915 	{
4916 		addstringtoinfstr(infstr, x_("ATTRP_"));
4917 		addstringtoinfstr(infstr, pp->protoname);
4918 		addstringtoinfstr(infstr, x_("_"));
4919 	} else
4920 	{
4921 		addstringtoinfstr(infstr, x_("ATTR_"));
4922 	}
4923 	addstringtoinfstr(infstr, name);
4924 	return(returninfstr(infstr));
4925 }
4926 
us_attrloadchoices(INTBIG numvar,VARIABLE * firstvar,INTBIG curcontrol,void * dia)4927 void us_attrloadchoices(INTBIG numvar, VARIABLE *firstvar, INTBIG curcontrol, void *dia)
4928 {
4929 	REGISTER VARIABLE *var;
4930 	REGISTER INTBIG i, protolen;
4931 	BOOLEAN found;
4932 	REGISTER CHAR *varname;
4933 	static CHAR *whattodisplay[] = {N_("Nothing"), N_("Value"), N_("Name&Value"),
4934 		N_("Name,Inherit,Value"), N_("Name,Inherit-All,Value")};
4935 	CHAR *newlang[5];
4936 	INTBIG maxshowoptions;
4937 
4938 	if (curcontrol == DATR_PORTATTRS)
4939 	{
4940 		protolen = estrlen(us_attrportprotoaddr->protoname);
4941 		maxshowoptions = 5;
4942 	} else
4943 	{
4944 		protolen = 0;
4945 		maxshowoptions = 3;
4946 	}
4947 	for(i=0; i<maxshowoptions; i++) newlang[i] = TRANSLATE(whattodisplay[i]);
4948 	DiaSetPopup(dia, DATR_WHATTOSHOW, maxshowoptions, newlang);
4949 	DiaLoadTextDialog(dia, DATR_ATTRLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
4950 	found = FALSE;
4951 	for(i=0; i<numvar; i++)
4952 	{
4953 		var = &firstvar[i];
4954 		varname = makename(var->key);
4955 		if (curcontrol == DATR_PORTATTRS)
4956 		{
4957 			if (namesamen(varname, x_("ATTRP_"), 6) == 0)
4958 			{
4959 				if (namesamen(&varname[6], us_attrportprotoaddr->protoname, protolen) == 0)
4960 				{
4961 					if (varname[6+protolen] == '_')
4962 					{
4963 						DiaStuffLine(dia, DATR_ATTRLIST, &varname[7+protolen]);
4964 						found = TRUE;
4965 					}
4966 				}
4967 			}
4968 		} else
4969 		{
4970 			if (namesamen(varname, x_("ATTR_"), 5) == 0)
4971 			{
4972 				DiaStuffLine(dia, DATR_ATTRLIST, &varname[5]);
4973 				found = TRUE;
4974 			}
4975 		}
4976 		if (curcontrol == DATR_CELLATTRS || curcontrol == DATR_NODEATTRS || curcontrol == DATR_ARCATTRS)
4977 		{
4978 			/* see if any cell, node, or arc variables are available to the user */
4979 			if (us_bettervariablename(varname) != 0)
4980 			{
4981 				DiaStuffLine(dia, DATR_ATTRLIST, varname);
4982 				found = TRUE;
4983 				continue;
4984 			}
4985 		}
4986 	}
4987 	if (!found)
4988 	{
4989 		DiaSelectLine(dia, DATR_ATTRLIST, -1);
4990 		DiaSetText(dia, DATR_XOFFSET, x_("0"));
4991 		DiaSetText(dia, DATR_YOFFSET, x_("0"));
4992 		DiaSetText(dia, DATR_ATTRVALUE, x_(""));
4993 		DiaSetPopupEntry(dia, DATR_WHATTOSHOW, 2);
4994 		DiaSetPopupEntry(dia, DATR_LANGUAGE, 0);
4995 		DiaSetText(dia, DATR_EVALUATION, x_(""));
4996 		DiaSetText(dia, DATR_ATTRNAME, x_(""));
4997 	} else
4998 	{
4999 		DiaSelectLine(dia, DATR_ATTRLIST, 0);
5000 		us_attrselectattributeline(curcontrol, 0, numvar, firstvar, dia);
5001 	}
5002 }
5003 
us_attrloadportlist(INTBIG curcontrol,void * dia)5004 void us_attrloadportlist(INTBIG curcontrol, void *dia)
5005 {
5006 	REGISTER INTBIG i, which;
5007 	REGISTER PORTPROTO *pp;
5008 	REGISTER void *infstr;
5009 
5010 	DiaLoadTextDialog(dia, DATR_PORTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
5011 	if (curcontrol == DATR_EXPORTATTRS || curcontrol == DATR_PORTATTRS)
5012 	{
5013 		/* port selected: show all ports */
5014 		if (curcontrol == DATR_EXPORTATTRS)
5015 		{
5016 			which = -1;
5017 			for(i=0, pp = us_attrnodeprotoaddr->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto, i++)
5018 			{
5019 				if (pp == us_attrexportprotoaddr) which = i;
5020 				infstr = initinfstr();
5021 				addstringtoinfstr(infstr, x_("> "));
5022 				addstringtoinfstr(infstr, pp->protoname);
5023 				DiaStuffLine(dia, DATR_PORTLIST, returninfstr(infstr));
5024 			}
5025 			if (which >= 0) DiaSelectLine(dia, DATR_PORTLIST, which);
5026 		} else
5027 		{
5028 			which = -1;
5029 			for(i=0, pp = us_attrnodeinstaddr->proto->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto, i++)
5030 			{
5031 				if (pp == us_attrportprotoaddr) which = i;
5032 				infstr = initinfstr();
5033 				addstringtoinfstr(infstr, x_("> "));
5034 				addstringtoinfstr(infstr, pp->protoname);
5035 				DiaStuffLine(dia, DATR_PORTLIST, returninfstr(infstr));
5036 			}
5037 			if (which >= 0) DiaSelectLine(dia, DATR_PORTLIST, which);
5038 		}
5039 		DiaUnDimItem(dia, DATR_ARRAYPORT);
5040 		DiaUnDimItem(dia, DATR_ARRAY_L);
5041 		DiaUnDimItem(dia, DATR_ADDPORT);
5042 		DiaUnDimItem(dia, DATR_REMOVEPORT);
5043 		DiaUnDimItem(dia, DATR_ADDALLPORTS);
5044 		DiaUnDimItem(dia, DATR_REMOVEALLPORTS);
5045 	} else
5046 	{
5047 		DiaDimItem(dia, DATR_ARRAYPORT);
5048 		DiaDimItem(dia, DATR_ARRAY_L);
5049 		DiaDimItem(dia, DATR_ADDPORT);
5050 		DiaDimItem(dia, DATR_REMOVEPORT);
5051 		DiaDimItem(dia, DATR_ADDALLPORTS);
5052 		DiaDimItem(dia, DATR_REMOVEALLPORTS);
5053 	}
5054 }
5055 
us_attrgetfactors(INTBIG curcontrol,INTBIG addr,INTBIG * numvar,VARIABLE ** firstvar)5056 void us_attrgetfactors(INTBIG curcontrol, INTBIG addr, INTBIG *numvar, VARIABLE **firstvar)
5057 {
5058 	REGISTER NODEPROTO *np;
5059 	REGISTER NODEINST *ni;
5060 	REGISTER PORTPROTO *pp;
5061 	REGISTER ARCINST *ai;
5062 
5063 	switch (curcontrol)
5064 	{
5065 		case DATR_CELLATTRS:
5066 			np = (NODEPROTO *)addr;
5067 			*numvar = np->numvar;
5068 			*firstvar = np->firstvar;
5069 			break;
5070 		case DATR_NODEATTRS:
5071 		case DATR_PORTATTRS:
5072 			ni = (NODEINST *)addr;
5073 			*numvar = ni->numvar;
5074 			*firstvar = ni->firstvar;
5075 			break;
5076 		case DATR_EXPORTATTRS:
5077 			pp = (PORTPROTO *)addr;
5078 			*numvar = pp->numvar;
5079 			*firstvar = pp->firstvar;
5080 			break;
5081 		case DATR_ARCATTRS:
5082 			ai = (ARCINST *)addr;
5083 			*numvar = ai->numvar;
5084 			*firstvar = ai->firstvar;
5085 			break;
5086 	}
5087 }
5088 
us_attrfindvarname(INTBIG curcontrol,INTBIG numvar,VARIABLE * firstvar,void * dia)5089 VARIABLE *us_attrfindvarname(INTBIG curcontrol, INTBIG numvar, VARIABLE *firstvar, void *dia)
5090 {
5091 	REGISTER INTBIG i, len;
5092 	REGISTER CHAR *pt, *varname;
5093 	REGISTER VARIABLE *var;
5094 
5095 	i = DiaGetCurLine(dia, DATR_ATTRLIST);
5096 	if (i < 0)
5097 	{
5098 		DiaMessageInDialog(_("Select an attribute name first"));
5099 		return(NOVARIABLE);
5100 	}
5101 	pt = DiaGetScrollLine(dia, DATR_ATTRLIST, i);
5102 	for(i=0; i<numvar; i++)
5103 	{
5104 		var = &firstvar[i];
5105 		varname = makename(var->key);
5106 		if (curcontrol == DATR_PORTATTRS)
5107 		{
5108 			if (namesamen(varname, x_("ATTRP_"), 6) != 0) continue;
5109 			len = estrlen(us_attrportprotoaddr->protoname);
5110 			if (namesamen(&varname[6], us_attrportprotoaddr->protoname, len) != 0) continue;
5111 			if (varname[6+len] != '_') continue;
5112 			if (namesame(&varname[7+len], pt) == 0) return(var);
5113 		} else
5114 		{
5115 			if (namesamen(varname, x_("ATTR_"), 5) != 0) continue;
5116 			if (namesame(&varname[5], pt) == 0) return(var);
5117 		}
5118 	}
5119 
5120 	/* didn't find name with "ATTR" prefix, look for name directly */
5121 	for(i=0; i<numvar; i++)
5122 	{
5123 		var = &firstvar[i];
5124 		varname = makename(var->key);
5125 		if (namesame(varname, pt) == 0) return(var);
5126 	}
5127 	return(NOVARIABLE);
5128 }
5129 
5130 /****************************** ATTRIBUTE ENUMERATION ******************************/
5131 
5132 /* Attributes enumeration */
5133 static DIALOGITEM us_manattrdialogitems[] =
5134 {
5135  /*  1 */ {0, {72,224,96,304}, BUTTON, N_("OK")},
5136  /*  2 */ {0, {72,12,96,92}, BUTTON, N_("Cancel")},
5137  /*  3 */ {0, {12,4,28,192}, MESSAGE, N_("Attributes name to enumerate:")},
5138  /*  4 */ {0, {12,196,28,316}, EDITTEXT, x_("")},
5139  /*  5 */ {0, {40,60,56,248}, BUTTON, N_("Check for this attribute")}
5140 };
5141 static DIALOG us_manattrdialog = {{75,75,180,400}, N_("Enumerate Attributes"), 0, 5, us_manattrdialogitems, 0, 0};
5142 
5143 /* special items for the "attribute enumerate" dialog: */
5144 #define DATE_ATTRNAME       4		/* Attribute name (edit text) */
5145 #define DATE_CHECKATTR      5		/* Check attribute existence (button) */
5146 
5147 static void us_findattr(CHAR *attrname, INTBIG fake);
5148 static void us_scanattrs(NODEPROTO *np, CHAR *attrname, INTBIG collect);
5149 
5150 #define NOENUMATTR ((ENUMATTR *)-1)
5151 
5152 typedef struct Ienumattr
5153 {
5154 	CHAR             *prefix;
5155 	INTBIG            foundtotal;
5156 	INTBIG            foundcount;
5157 	INTBIG           *found;
5158 	INTBIG            foundlow;
5159 	INTBIG            foundhigh;
5160 	INTBIG            added;
5161 	struct Ienumattr *nextenumattr;
5162 } ENUMATTR;
5163 ENUMATTR *us_firstenumattr;
5164 
us_attrenumdlog(void)5165 INTBIG us_attrenumdlog(void)
5166 {
5167 	INTBIG itemHit;
5168 	REGISTER void *dia;
5169 
5170 	dia = DiaInitDialog(&us_manattrdialog);
5171 	if (dia == 0) return(0);
5172 
5173 	/* loop until done */
5174 	for(;;)
5175 	{
5176 		itemHit = DiaNextHit(dia);
5177 		if (itemHit == OK || itemHit == CANCEL) break;
5178 		if (itemHit == DATE_CHECKATTR)
5179 		{
5180 			us_firstenumattr = NOENUMATTR;
5181 			us_findattr(DiaGetText(dia, DATE_ATTRNAME), 1);
5182 		}
5183 	}
5184 	if (itemHit == OK)
5185 	{
5186 		us_firstenumattr = NOENUMATTR;
5187 		us_findattr(DiaGetText(dia, DATE_ATTRNAME), 0);
5188 	}
5189 	DiaDoneDialog(dia);
5190 	return(0);
5191 }
5192 
us_findattr(CHAR * attrname,INTBIG fake)5193 void us_findattr(CHAR *attrname, INTBIG fake)
5194 {
5195 	REGISTER NODEPROTO *np, *onp;
5196 	CHAR *fullattrname;
5197 	REGISTER INTBIG cellcount, i;
5198 	REGISTER ENUMATTR *ea, *nextea;
5199 
5200 	/* find the current cell */
5201 	np = getcurcell();
5202 	if (np == NONODEPROTO) return;
5203 
5204 	fullattrname = (CHAR *)emalloc((estrlen(attrname)+6) * SIZEOFCHAR, us_tool->cluster);
5205 	if (fullattrname == 0) return;
5206 	estrcpy(fullattrname, x_("ATTR_"));
5207 	estrcat(fullattrname, attrname);
5208 
5209 	if ((np->cellview->viewstate&MULTIPAGEVIEW) != 0)
5210 	{
5211 		/* examine this cell and all others in the multipage view */
5212 		cellcount = 0;
5213 		FOR_CELLGROUP(onp, np)
5214 		{
5215 			us_scanattrs(onp, fullattrname, 1);
5216 			cellcount++;
5217 		}
5218 		ttyputmsg(_("Examining attribute '%s' in %ld schematic pages of cell %s"),
5219 			attrname, cellcount, np->protoname);
5220 	} else
5221 	{
5222 		/* just examine this cell */
5223 		us_scanattrs(np, fullattrname, 1);
5224 		ttyputmsg(_("Examining attribute '%s' in cell %s"),
5225 			attrname, describenodeproto(np));
5226 	}
5227 
5228 	/* analyze the results */
5229 	for(ea = us_firstenumattr; ea != NOENUMATTR; ea = ea->nextenumattr)
5230 	{
5231 		ea->foundlow = ea->foundhigh = 0;
5232 		if (ea->foundcount <= 0) continue;
5233 		esort(ea->found, ea->foundcount, SIZEOFINTBIG, sort_intbigascending);
5234 		ea->foundlow = ea->found[0];
5235 		ea->foundhigh = ea->found[ea->foundcount-1];
5236 		for(i=1; i<ea->foundcount; i++)
5237 			if (ea->found[i-1] == ea->found[i]) break;
5238 		if (i < ea->foundcount)
5239 			ttyputerr(_("ERROR: attribute has the value '%s%ld' more than once"),
5240 				ea->prefix, ea->found[i]);
5241 	}
5242 
5243 	if (fake != 0)
5244 	{
5245 		/* report what would be added */
5246 		for(ea = us_firstenumattr; ea != NOENUMATTR; ea = ea->nextenumattr)
5247 		{
5248 			if (ea->added == 0) continue;
5249 			ttyputmsg(_("Will add %ld values starting at '%s%ld'"), ea->added,
5250 				ea->prefix, ea->foundhigh+1);
5251 		}
5252 	} else
5253 	{
5254 		for(ea = us_firstenumattr; ea != NOENUMATTR; ea = ea->nextenumattr)
5255 			ea->added = 0;
5256 		if ((np->cellview->viewstate&MULTIPAGEVIEW) != 0)
5257 		{
5258 			/* examine this cell and all others in the multipage view */
5259 			FOR_CELLGROUP(onp, np)
5260 				us_scanattrs(onp, fullattrname, 0);
5261 		} else
5262 		{
5263 			/* just examine this cell */
5264 			us_scanattrs(np, fullattrname, 0);
5265 		}
5266 
5267 		/* report what was added */
5268 		for(ea = us_firstenumattr; ea != NOENUMATTR; ea = ea->nextenumattr)
5269 		{
5270 			if (ea->added == 0) continue;
5271 			if (ea->added == 1)
5272 			{
5273 				ttyputmsg(_("Added value '%s%ld'"), ea->prefix, ea->foundhigh);
5274 			} else
5275 			{
5276 				ttyputmsg(_("Added values '%s%ld' to '%s%ld'"), ea->prefix,
5277 					ea->foundhigh-ea->added+1, ea->prefix, ea->foundhigh);
5278 			}
5279 		}
5280 	}
5281 
5282 	/* free memory */
5283 	for(ea = us_firstenumattr; ea != NOENUMATTR; ea = nextea)
5284 	{
5285 		nextea = ea->nextenumattr;
5286 		efree((CHAR *)ea->prefix);
5287 		efree((CHAR *)ea);
5288 	}
5289 
5290 	efree(fullattrname);
5291 }
5292 
5293 /*
5294  * Routine to examine cell "np" for attributes named "attrname".
5295  * If "collect" is positive, collect the names in the global list.
5296  * If "collect" is zero, assign new values to attributes ending with "?".
5297  */
us_scanattrs(NODEPROTO * np,CHAR * attrname,INTBIG collect)5298 void us_scanattrs(NODEPROTO *np, CHAR *attrname, INTBIG collect)
5299 {
5300 	REGISTER NODEINST *ni;
5301 	REGISTER VARIABLE *var;
5302 	REGISTER CHAR *pt, *numericpart, save, *start;
5303 	REGISTER INTBIG *newfound, newtotal, i, index;
5304 	REGISTER ENUMATTR *ea;
5305 	UINTBIG descript[TEXTDESCRIPTSIZE];
5306 	REGISTER void *infstr;
5307 
5308 	for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
5309 	{
5310 		var = getval((INTBIG)ni, VNODEINST, VSTRING, attrname);
5311 		if (var == NOVARIABLE) continue;
5312 		/* code may be string but my evaluate to non-string */
5313 		if ( (var->type & VTYPE) != VSTRING) continue;
5314 
5315 		/* break string into text part and numeric or "?" part */
5316 		numericpart = 0;
5317 		start = (CHAR *)var->addr;
5318 		for(pt = start; *pt != 0; pt++)
5319 		{
5320 			if (estrcmp(pt, x_("?")) == 0)
5321 			{
5322 				numericpart = pt;
5323 				break;
5324 			}
5325 			if (isdigit(*pt) != 0)
5326 			{
5327 				if (numericpart == 0) numericpart = pt;
5328 			} else numericpart = 0;
5329 		}
5330 		if (numericpart == 0) continue;
5331 
5332 		/* include this one */
5333 		save = *numericpart;
5334 		*numericpart = 0;
5335 		for(ea = us_firstenumattr; ea != NOENUMATTR; ea = ea->nextenumattr)
5336 			if (namesame(ea->prefix, start) == 0) break;
5337 		if (ea == NOENUMATTR)
5338 		{
5339 			if (collect == 0) continue;
5340 
5341 			/* this prefix has not been seen yet: add it */
5342 			ea = (ENUMATTR *)emalloc(sizeof (ENUMATTR), us_tool->cluster);
5343 			if (ea == 0) return;
5344 			(void)allocstring(&ea->prefix, start, us_tool->cluster);
5345 			ea->foundtotal = ea->foundcount = ea->added = 0;
5346 			ea->nextenumattr = us_firstenumattr;
5347 			us_firstenumattr = ea;
5348 		}
5349 		*numericpart = save;
5350 		if (*numericpart == '?')
5351 		{
5352 			ea->added++;
5353 			if (collect != 0) continue;
5354 			infstr = initinfstr();
5355 			ea->foundhigh++;
5356 			formatinfstr(infstr, x_("%s%ld"), ea->prefix, ea->foundhigh);
5357 			TDCOPY(descript, var->textdescript);
5358 			startobjectchange((INTBIG)ni, VNODEINST);
5359 			var = setval((INTBIG)ni, VNODEINST, attrname, (INTBIG)returninfstr(infstr),
5360 				var->type);
5361 			if (var != NOVARIABLE)
5362 			{
5363 				TDCOPY(var->textdescript, descript);
5364 			}
5365 			endobjectchange((INTBIG)ni, VNODEINST);
5366 		} else
5367 		{
5368 			if (collect == 0) continue;
5369 			index = myatoi(numericpart);
5370 			if (ea->foundcount >= ea->foundtotal)
5371 			{
5372 				newtotal = ea->foundtotal * 2;
5373 				if (newtotal <= ea->foundcount) newtotal = ea->foundcount + 5;
5374 				newfound = (INTBIG *)emalloc(newtotal * SIZEOFINTBIG, us_tool->cluster);
5375 				if (newfound == 0) return;
5376 				for(i=0; i<ea->foundcount; i++)
5377 					newfound[i] = ea->found[i];
5378 				if (ea->foundtotal > 0) efree((CHAR *)ea->found);
5379 				ea->found = newfound;
5380 				ea->foundtotal = newtotal;
5381 			}
5382 			ea->found[ea->foundcount++] = index;
5383 		}
5384 	}
5385 }
5386 
5387 /****************************** ATTRIBUTE REPORT ******************************/
5388 
5389 /* Report for Attribute */
5390 static DIALOGITEM us_report_attrdialogitems[] =
5391 {
5392  /*  1 */ {0, {12,8,28,112}, MESSAGE, N_("Attribute name:")},
5393  /*  2 */ {0, {12,116,28,224}, EDITTEXT, x_("")},
5394  /*  3 */ {0, {60,92,84,224}, DEFBUTTON, N_("Generate Report")},
5395  /*  4 */ {0, {36,32,52,112}, CHECK, N_("To file:")},
5396  /*  5 */ {0, {36,116,52,224}, EDITTEXT, x_("")},
5397  /*  6 */ {0, {60,8,84,76}, BUTTON, N_("Cancel")}
5398 };
5399 static DIALOG us_report_attrdialog = {{75,75,168,309}, N_("Attribute Report"), 0, 6, us_report_attrdialogitems, 0, 0};
5400 
5401 /* special items for the "report for attribute" dialog: */
5402 #define DATRR_STATE_TOFILE		1
5403 #define DATRR_ATTRNAME			2
5404 #define DATRR_GENERATE			3
5405 #define DATRR_TOFILE			4
5406 #define DATRR_FILENAME			5
5407 #define DATRR_CANCEL			6
5408 
5409 static void us_reportattr(NODEPROTO *np, CHAR *attr, FILE *fd);
5410 
us_attrreportdlog(void)5411 INTBIG us_attrreportdlog(void)
5412 {
5413 	INTBIG itemHit;
5414 	CHAR *rename, *truename;
5415 	REGISTER FILE *fd;
5416 	REGISTER void *infstr;
5417 	REGISTER void *dia;
5418 	static INTBIG laststate = 0;
5419 	static CHAR lastattr[300] = {x_("")};
5420 	static CHAR lastfile[300] = {x_("")};
5421 
5422 	dia = DiaInitDialog(&us_report_attrdialog);
5423 	if (dia == 0) return(0);
5424 	if ((laststate&DATRR_STATE_TOFILE) != 0) DiaSetControl(dia, DATRR_TOFILE, 1);
5425 	DiaSetText(dia, -DATRR_ATTRNAME, lastattr);
5426 	DiaSetText(dia, -DATRR_FILENAME, lastfile);
5427 
5428 	/* loop until done */
5429 	for(;;)
5430 	{
5431 		itemHit = DiaNextHit(dia);
5432 		if (itemHit == DATRR_CANCEL) break;
5433 		if (itemHit == DATRR_TOFILE)
5434 		{
5435 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
5436 			continue;
5437 		}
5438 		if (itemHit == DATRR_GENERATE)
5439 		{
5440 			if (DiaValidEntry(dia, DATRR_ATTRNAME)==0)
5441 			{
5442 				ttyputmsg(_("Invalid attribute name"));
5443 				continue;
5444 			}
5445 			estrcpy(lastattr, DiaGetText(dia, DATRR_ATTRNAME));
5446 			if (DiaGetControl(dia, DATRR_TOFILE))
5447 			{
5448 				if (DiaValidEntry(dia, DATRR_FILENAME)==0)
5449 				{
5450 					ttyputmsg(_("Invalid file name"));
5451 					continue;
5452 				}
5453 				estrcpy(lastfile, DiaGetText(dia, DATRR_FILENAME));
5454 			}
5455 
5456 			infstr = initinfstr();
5457 			formatinfstr(infstr, x_("%-12s\t%-12s\t%s\t%s\n"), x_("node"), x_("name"), lastattr, x_("hierarchical path"));
5458 
5459 			if (DiaGetControl(dia, DATRR_TOFILE))
5460 			{
5461 				/* if file already exists, rename it first */
5462 				if( fileexistence(lastfile) == 1)
5463 				{
5464 					rename = (CHAR *)emalloc((estrlen(lastfile)+15) * SIZEOFCHAR, el_tempcluster);
5465 					(void)estrcpy(rename, lastfile);
5466 					(void)estrcat(rename, x_("~"));
5467 					if (fileexistence(rename) == 1) (void)eunlink(rename);
5468 					if (erename(lastfile, rename) != 0)
5469 						ttyputerr(_("Could not rename file '%s' to '%s'"), lastfile, rename);
5470 					efree(rename);
5471 				}
5472 				fd = xcreate(lastfile, io_filetypetlib, 0, &truename);
5473 				xputs(returninfstr(infstr), fd);
5474 			} else
5475 			{
5476 				ttyputmsg(_("%s"), returninfstr(infstr));
5477 				fd = NULL;
5478 			}
5479 			begintraversehierarchy();
5480 			us_reportattr(NONODEPROTO, lastattr, fd);
5481 			endtraversehierarchy();
5482 			if (fd != NULL) xclose(fd);
5483 			break;
5484 		}
5485 	}
5486 	if (itemHit == DATRR_GENERATE)
5487 	{
5488 		if (DiaGetControl(dia, DATRR_TOFILE) != 0) laststate |= DATRR_STATE_TOFILE; else
5489 			laststate &= ~DATRR_STATE_TOFILE;
5490 	}
5491 	DiaDoneDialog(dia);
5492 	return(0);
5493 }
5494 
5495 /*
5496  * Routine to generate attribute report
5497  */
us_reportattr(NODEPROTO * np,CHAR * attr,FILE * fd)5498 void us_reportattr(NODEPROTO *np, CHAR *attr, FILE *fd)
5499 {
5500 	REGISTER NODEINST *ni;
5501 	         NODEINST **hier;
5502 	REGISTER INTBIG attrkey, i, arraysize;
5503 			 INTBIG *indexlist, depth;
5504 	REGISTER NODEPROTO *cnp;
5505 	REGISTER VARIABLE *var, *varn, *varnn;
5506 	void *infstr;
5507 	CHAR temp[50];
5508 
5509 	/* if np == NONODEPROTO, this is top level call */
5510 	if (np == NONODEPROTO) np = getcurcell();
5511 	if (np == NONODEPROTO)
5512 	{
5513 		ttyputerr(_("No cell in current window"));
5514 		return;
5515 	}
5516 
5517 	/* make key */
5518 	infstr = initinfstr();
5519 	formatinfstr(infstr, x_("ATTR_%s"), attr);
5520 	attrkey = makekey(returninfstr(infstr));
5521 
5522 	/* search instances for attr */
5523 	for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
5524 	{
5525 		/* recurse */
5526 		cnp = contentsview(ni->proto);
5527 		if (cnp == NONODEPROTO) cnp = ni->proto;
5528 		if (cnp != np) /* ignore icon view */
5529 		{
5530 			arraysize = ni->arraysize;
5531 			if (arraysize == 0) arraysize = 1;
5532 			for(i=0; i<arraysize; i++)
5533 			{
5534 				downhierarchy(ni, cnp, i);
5535 				us_reportattr(cnp, attr, fd);
5536 				uphierarchy();
5537 			}
5538 		}
5539 
5540 		/* report var, unless it is on the icon view */
5541 		var = getvalkey((INTBIG)ni, VNODEINST, -1, attrkey);
5542 		if (var != NOVARIABLE && cnp != np)
5543 		{
5544 			varn = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
5545 			infstr = initinfstr();
5546 			CHAR *protoname = ni->proto->primindex == 0 ? ni->proto->protoname : ni->proto->protoname;
5547 			if (varn == NOVARIABLE)
5548 			{
5549 				esnprintf(temp, 50, x_("noname"));
5550 				formatinfstr(infstr, x_("%-12s\t%-12s\t"), protoname, temp);
5551 			}
5552 			else
5553 				formatinfstr(infstr, x_("%-12s\t%-12s\t"), protoname, varn->addr);
5554 			if ((var->type & VTYPE) == VFLOAT || (var->type & VTYPE) == VDOUBLE)
5555 				formatinfstr(infstr, x_("%4.2f\t"), castfloat(var->addr));
5556 			else if ((var->type & VTYPE) == VINTEGER)
5557 				formatinfstr(infstr, x_("%ld\t"), var->addr);
5558 			else if ((var->type & VTYPE) == VCHAR)
5559 				formatinfstr(infstr, x_("%c\t"), var->addr);
5560 			else if ((var->type & VTYPE) == VSTRING)
5561 				formatinfstr(infstr, x_("%s\t"), var->addr);
5562 			else
5563 				formatinfstr(infstr, x_("INVALID_TYPE\t"));
5564 			gettraversalpath(np, el_curwindowpart, &hier, &indexlist, &depth, 0);
5565 			for(i=0; i<depth; i++)
5566 			{
5567 				varnn = getvalkey((INTBIG)(hier[i]), VNODEINST, VSTRING, el_node_name_key);
5568 				if (varnn != NOVARIABLE)
5569 				{
5570 					if (indexlist[i] == 0)
5571 						formatinfstr(infstr, x_("%s[%s]."), hier[i]->proto->protoname, varnn->addr);
5572 					else
5573 						formatinfstr(infstr, x_("%s[%s[%ld]]."), hier[i]->proto->protoname, varnn->addr, indexlist[i]);
5574 				} else
5575 				{
5576 					if (indexlist[i] == 0)
5577 						formatinfstr(infstr, x_("%s[]."), hier[i]->proto->protoname);
5578 					else
5579 						formatinfstr(infstr, x_("%s[%ld]."), hier[i]->proto->protoname, indexlist[i]);
5580 				}
5581 			}
5582 			if (varn != NOVARIABLE)
5583 				formatinfstr(infstr, x_("%s\n"), varn->addr);
5584 			else
5585 				formatinfstr(infstr, x_("noname\n"));
5586 			if (fd == NULL)
5587 				ttyputmsg(_("%s"), returninfstr(infstr));
5588 			else
5589 				xputs(returninfstr(infstr), fd);
5590 		}
5591 	}
5592 }
5593 
5594 /****************************** COPYRIGHT OPTIONS ******************************/
5595 
5596 /* Copyright Options */
5597 static DIALOGITEM us_crodialogitems[] =
5598 {
5599  /*  1 */ {0, {168,272,192,352}, BUTTON, N_("OK")},
5600  /*  2 */ {0, {165,76,189,156}, BUTTON, N_("Cancel")},
5601  /*  3 */ {0, {4,4,20,432}, MESSAGE, N_("Copyright information can be added to every generated deck.")},
5602  /*  4 */ {0, {72,4,88,268}, RADIO, N_("Use copyright message from file:")},
5603  /*  5 */ {0, {96,28,128,292}, EDITTEXT, x_("")},
5604  /*  6 */ {0, {100,300,124,372}, BUTTON, N_("Browse")},
5605  /*  7 */ {0, {136,28,152,432}, MESSAGE, N_("Do not put comment characters in this file.")},
5606  /*  8 */ {0, {48,4,64,268}, RADIO, N_("No copyright message")}
5607 };
5608 static DIALOG us_crodialog = {{75,75,276,517}, N_("Copyright Options"), 0, 8, us_crodialogitems, 0, 0};
5609 
5610 /* special items for the "copyright options" dialog: */
5611 #define DCRO_USECOPYRIGHT 4		/* use copyright notice (radio) */
5612 #define DCRO_FILENAME     5		/* copyright file name (edit text) */
5613 #define DCRO_BROWSE       6		/* browse for copyright file (button) */
5614 #define DCRO_NOCOPYRIGHT  8		/* no copyright notice (radio) */
5615 
us_copyrightdlog(void)5616 INTBIG us_copyrightdlog(void)
5617 {
5618 	REGISTER void *dia, *infstr;
5619 	REGISTER CHAR *initialfile, *pt;
5620 	CHAR *subparams[3];
5621 	REGISTER INTBIG itemHit, i, oldplease;
5622 	REGISTER VARIABLE *var;
5623 
5624 	dia = DiaInitDialog(&us_crodialog);
5625 	if (dia == 0) return(0);
5626 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING, us_copyright_file_key);
5627 	if (var == NOVARIABLE)
5628 	{
5629 		initialfile = x_("");
5630 		DiaSetControl(dia, DCRO_NOCOPYRIGHT, 1);
5631 		DiaDimItem(dia, DCRO_FILENAME);
5632 	} else
5633 	{
5634 		initialfile = (CHAR *)var->addr;
5635 		DiaSetControl(dia, DCRO_USECOPYRIGHT, 1);
5636 		DiaUnDimItem(dia, DCRO_FILENAME);
5637 		DiaSetText(dia, DCRO_FILENAME, initialfile);
5638 	}
5639 
5640 	for(;;)
5641 	{
5642 		itemHit = DiaNextHit(dia);
5643 		if (itemHit == OK || itemHit == CANCEL) break;
5644 		if (itemHit == DCRO_NOCOPYRIGHT || itemHit == DCRO_USECOPYRIGHT)
5645 		{
5646 			DiaSetControl(dia, DCRO_NOCOPYRIGHT, 0);
5647 			DiaSetControl(dia, DCRO_USECOPYRIGHT, 0);
5648 			DiaSetControl(dia, itemHit, 1);
5649 			if (itemHit == DCRO_NOCOPYRIGHT)
5650 			{
5651 				DiaDimItem(dia, DCRO_FILENAME);
5652 				continue;
5653 			}
5654 			if (*DiaGetText(dia, DCRO_FILENAME) != 0)
5655 			{
5656 				DiaUnDimItem(dia, DCRO_FILENAME);
5657 				continue;
5658 			}
5659 			itemHit = DCRO_BROWSE;
5660 			/* fall into next case */
5661 		}
5662 		if (itemHit == DCRO_BROWSE)
5663 		{
5664 			/* set copyright file */
5665 			oldplease = el_pleasestop;
5666 			infstr = initinfstr();
5667 			addstringtoinfstr(infstr, x_("text/"));
5668 			addstringtoinfstr(infstr, _("Copyright File"));
5669 			i = ttygetparam(returninfstr(infstr), &us_colorreadp, 1, subparams);
5670 			el_pleasestop = oldplease;
5671 			if (i != 0 && subparams[0][0] != 0)
5672 			{
5673 				DiaUnDimItem(dia, DCRO_FILENAME);
5674 				DiaSetText(dia, DCRO_FILENAME, subparams[0]);
5675 				DiaSetControl(dia, DCRO_NOCOPYRIGHT, 0);
5676 				DiaSetControl(dia, DCRO_USECOPYRIGHT, 1);
5677 			}
5678 			continue;
5679 		}
5680 	}
5681 	if (itemHit == OK)
5682 	{
5683 		if (DiaGetControl(dia, DCRO_NOCOPYRIGHT) != 0)
5684 		{
5685 			if (var != NOVARIABLE)
5686 				delvalkey((INTBIG)us_tool, VTOOL, us_copyright_file_key);
5687 		} else
5688 		{
5689 			pt = DiaGetText(dia, DCRO_FILENAME);
5690 			if (namesame(pt, initialfile) != 0)
5691 				(void)setvalkey((INTBIG)us_tool, VTOOL, us_copyright_file_key, (INTBIG)pt, VSTRING);
5692 		}
5693 	}
5694 	DiaDoneDialog(dia);
5695 	return(0);
5696 }
5697 
5698 /****************************** CELL PARAMETERS ******************************/
5699 
5700 /* Cell Parameters */
5701 static DIALOGITEM us_paramdialogitems[] =
5702 {
5703  /*  1 */ {0, {192,424,216,504}, BUTTON, N_("Done")},
5704  /*  2 */ {0, {36,216,52,332}, MESSAGE, N_("New Parameter:")},
5705  /*  3 */ {0, {28,8,216,208}, SCROLL, x_("")},
5706  /*  4 */ {0, {36,336,52,504}, EDITTEXT, x_("")},
5707  /*  5 */ {0, {60,336,92,504}, EDITTEXT, x_("")},
5708  /*  6 */ {0, {60,216,76,332}, MESSAGE, N_("Default Value:")},
5709  /*  7 */ {0, {152,216,176,352}, BUTTON, N_("Create Parameter")},
5710  /*  8 */ {0, {8,8,24,504}, MESSAGE, N_("Parameters on cell %s:")},
5711  /*  9 */ {0, {152,368,176,504}, BUTTON, N_("Delete Parameter")},
5712  /* 10 */ {0, {124,216,140,332}, MESSAGE, N_("Units:")},
5713  /* 11 */ {0, {124,336,140,504}, POPUP, x_("")},
5714  /* 12 */ {0, {100,216,116,332}, MESSAGE, N_("Language:")},
5715  /* 13 */ {0, {100,336,116,504}, POPUP, x_("")}
5716 };
5717 static DIALOG us_paramdialog = {{75,75,300,589}, N_("Cell Parameters"), 0, 13, us_paramdialogitems, 0, 0};
5718 
5719 /* special items for the "cell parameter" dialog: */
5720 #define DATP_PARLIST     3		/* list of parameters (scroll) */
5721 #define DATP_PARNAME     4		/* new parameter name (edit text) */
5722 #define DATP_PARVALUE    5		/* new parameter value (edit text) */
5723 #define DATP_MAKEPAR     7		/* create parameter (button) */
5724 #define DATP_TITLE       8		/* title of list (message) */
5725 #define DATP_DELPAR      9		/* delete parameter (button) */
5726 #define DATP_UNITS      11		/* parameter units (popup) */
5727 #define DATP_LANGUAGE   13		/* parameter language (popup) */
5728 
us_attrparamdlog(void)5729 INTBIG us_attrparamdlog(void)
5730 {
5731 	REGISTER INTBIG itemHit, i, j, found, len, units, listlen, lang;
5732 	BOOLEAN showparams;
5733 	INTBIG newtype, newval, xoff, yoff;
5734 	UINTBIG descript[TEXTDESCRIPTSIZE];
5735 	REGISTER CHAR *pt, *varname, **languages;
5736 	CHAR *newlang[8];
5737 	REGISTER NODEINST *ni;
5738 	REGISTER LIBRARY *lib;
5739 	REGISTER NODEPROTO *np, *onp;
5740 	REGISTER VARIABLE *var, *fvar, *curvar, *wantvar;
5741 	REGISTER void *infstr, *dia;
5742 
5743 	np = us_needcell();
5744 	if (np == NONODEPROTO) return(0);
5745 	dia = DiaInitDialog(&us_paramdialog);
5746 	if (dia == 0) return(0);
5747 	DiaInitTextDialog(dia, DATP_PARLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
5748 		SCSELMOUSE|SCREPORT);
5749 	for(i=0; i<8; i++) newlang[i] = TRANSLATE(us_unitnames[i]);
5750 	DiaSetPopup(dia, DATP_UNITS, 8, newlang);
5751 	languages = us_languagechoices();
5752 	DiaSetPopup(dia, DATP_LANGUAGE, 4, languages);
5753 	infstr = initinfstr();
5754 	formatinfstr(infstr, _("Parameters on cell %s:"), describenodeproto(np));
5755 	DiaSetText(dia, DATP_TITLE, returninfstr(infstr));
5756 	showparams = TRUE;
5757 	wantvar = NOVARIABLE;
5758 	curvar = NOVARIABLE;
5759 	for(;;)
5760 	{
5761 		if (showparams)
5762 		{
5763 			DiaLoadTextDialog(dia, DATP_PARLIST, DiaNullDlogList, DiaNullDlogItem,
5764 				DiaNullDlogDone, 0);
5765 			j = -1;
5766 			found = 0;
5767 			for(i=0; i<np->numvar; i++)
5768 			{
5769 				var = &np->firstvar[i];
5770 				if (TDGETISPARAM(var->textdescript) == 0) continue;
5771 				infstr = initinfstr();
5772 				formatinfstr(infstr, x_("%s (default: %s)"), truevariablename(var),
5773 					describevariable(var, -1, -1));
5774 				DiaStuffLine(dia, DATP_PARLIST, returninfstr(infstr));
5775 				if (found == 0) j = found;
5776 				if (var == wantvar) j = found;
5777 				found++;
5778 			}
5779 			DiaSelectLine(dia, DATP_PARLIST, j);
5780 			showparams = FALSE;
5781 			itemHit = DATP_PARLIST;
5782 		} else
5783 		{
5784 			/* didn't just update list: get an event */
5785 			itemHit = DiaNextHit(dia);
5786 		}
5787 		if (itemHit == OK) break;
5788 		if (itemHit == DATP_PARLIST)
5789 		{
5790 			/* clicked in parameter list: */
5791 			DiaDimItem(dia, DATP_DELPAR);
5792 			DiaSetPopupEntry(dia, DATP_UNITS, 0);
5793 			DiaSetPopupEntry(dia, DATP_LANGUAGE, 0);
5794 			i = DiaGetCurLine(dia, DATP_PARLIST);
5795 			if (i < 0) continue;
5796 			pt = DiaGetScrollLine(dia, DATP_PARLIST, i);
5797 			for(len=0; pt[len] != 0; len++)
5798 				if (estrncmp(&pt[len], x_(" ("), 2) == 0) break;
5799 			for(i=0; i<np->numvar; i++)
5800 			{
5801 				curvar = &np->firstvar[i];
5802 				if (TDGETISPARAM(curvar->textdescript) != 0)
5803 				{
5804 					if (namesamen(pt, truevariablename(curvar), len) == 0) break;
5805 				}
5806 				curvar = NOVARIABLE;
5807 			}
5808 			if (curvar == NOVARIABLE) continue;
5809 			DiaUnDimItem(dia, DATP_DELPAR);
5810 			DiaSetPopupEntry(dia, DATP_UNITS, TDGETUNITS(curvar->textdescript));
5811 			switch (curvar->type&(VCODE1|VCODE2))
5812 			{
5813 				case 0:     DiaSetPopupEntry(dia, DATP_LANGUAGE, 0);   break;
5814 				case VTCL:  DiaSetPopupEntry(dia, DATP_LANGUAGE, 1);   break;
5815 				case VLISP: DiaSetPopupEntry(dia, DATP_LANGUAGE, 2);   break;
5816 				case VJAVA: DiaSetPopupEntry(dia, DATP_LANGUAGE, 3);   break;
5817 			}
5818 			DiaSetText(dia, DATP_PARNAME, truevariablename(curvar));
5819 			DiaSetText(dia, DATP_PARVALUE, describevariable(curvar, -1, -1));
5820 			continue;
5821 		}
5822 		if (itemHit == DATP_PARVALUE || itemHit == DATP_UNITS ||
5823 			itemHit == DATP_LANGUAGE)
5824 		{
5825 			/* name must match current variable */
5826 			if (curvar == NOVARIABLE) continue;
5827 			varname = DiaGetText(dia, DATP_PARNAME);
5828 			if (namesame(varname, truevariablename(curvar)) != 0) continue;
5829 
5830 			/* change the scroll line */
5831 			listlen = DiaGetNumScrollLines(dia, DATP_PARLIST);
5832 			for(i=0; i<listlen; i++)
5833 			{
5834 				pt = DiaGetScrollLine(dia, DATP_PARLIST, i);
5835 				if (namesamen(pt, varname, estrlen(varname)) == 0)
5836 				{
5837 					infstr = initinfstr();
5838 					formatinfstr(infstr, x_("%s (default: %s)"), varname,
5839 						DiaGetText(dia, DATP_PARVALUE));
5840 					DiaSetScrollLine(dia, DATP_PARLIST, i, returninfstr(infstr));
5841 					break;
5842 				}
5843 			}
5844 
5845 			/* change the variable on the cell */
5846 			us_undrawcellvariable(curvar, np);
5847 			units = DiaGetPopupEntry(dia, DATP_UNITS);
5848 			getsimpletype(DiaGetText(dia, DATP_PARVALUE), &newtype, &newval, units);
5849 			newtype |= VDISPLAY;
5850 			lang = DiaGetPopupEntry(dia, DATP_LANGUAGE);
5851 			if (lang != 0)
5852 			{
5853 				switch (lang)
5854 				{
5855 					case 1: newtype |= VTCL;    break;
5856 					case 2: newtype |= VLISP;   break;
5857 					case 3: newtype |= VJAVA;   break;
5858 				}
5859 				newval = (INTBIG)DiaGetText(dia, DATP_PARVALUE);
5860 			}
5861 			curvar = setvalkey((INTBIG)np, VNODEPROTO, curvar->key, newval, newtype);
5862 			if (curvar != NOVARIABLE)
5863 			{
5864 				TDSETISPARAM(curvar->textdescript, VTISPARAMETER);
5865 				TDSETINHERIT(curvar->textdescript, VTINHERIT);
5866 				TDSETDISPPART(curvar->textdescript, VTDISPLAYNAMEVALINH);
5867 				TDSETUNITS(curvar->textdescript, units);
5868 			}
5869 			us_drawcellvariable(curvar, np);
5870 			continue;
5871 		}
5872 		if (itemHit == DATP_MAKEPAR)
5873 		{
5874 			if (!DiaValidEntry(dia, DATP_PARNAME)) continue;
5875 			units = DiaGetPopupEntry(dia, DATP_UNITS);
5876 			getsimpletype(DiaGetText(dia, DATP_PARVALUE), &newtype, &newval, units);
5877 			infstr = initinfstr();
5878 			varname = DiaGetText(dia, DATP_PARNAME);
5879 			formatinfstr(infstr, x_("ATTR_%s"), varname);
5880 			us_getnewparameterpos(np, &xoff, &yoff);
5881 			newtype |= VDISPLAY;
5882 			lang = DiaGetPopupEntry(dia, DATP_LANGUAGE);
5883 			if (lang != 0)
5884 			{
5885 				switch (lang)
5886 				{
5887 					case 1: newtype |= VTCL;    break;
5888 					case 2: newtype |= VLISP;   break;
5889 					case 3: newtype |= VJAVA;   break;
5890 				}
5891 				newval = (INTBIG)DiaGetText(dia, DATP_PARVALUE);
5892 			}
5893 			wantvar = setval((INTBIG)np, VNODEPROTO, returninfstr(infstr), newval, newtype);
5894 			if (wantvar != NOVARIABLE)
5895 			{
5896 				defaulttextsize(6, wantvar->textdescript);
5897 				TDSETISPARAM(wantvar->textdescript, VTISPARAMETER);
5898 				TDSETINHERIT(wantvar->textdescript, VTINHERIT);
5899 				TDSETDISPPART(wantvar->textdescript, VTDISPLAYNAMEVALINH);
5900 				TDSETUNITS(wantvar->textdescript, units);
5901 				TDSETOFF(wantvar->textdescript, xoff, yoff);
5902 				us_drawcellvariable(wantvar, np);
5903 			}
5904 
5905 			showparams = TRUE;
5906 			continue;
5907 		}
5908 		if (itemHit == DATP_DELPAR)
5909 		{
5910 			if (curvar == NOVARIABLE) continue;
5911 			us_undrawcellvariable(curvar, np);
5912 			(void)delvalkey((INTBIG)np, VNODEPROTO, curvar->key);
5913 			wantvar = NOVARIABLE;
5914 			showparams = TRUE;
5915 			continue;
5916 		}
5917 	}
5918 	DiaDoneDialog(dia);
5919 
5920 	/* update all instances */
5921 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
5922 	{
5923 		for(onp = lib->firstnodeproto; onp != NONODEPROTO; onp = onp->nextnodeproto)
5924 		{
5925 			for(ni = onp->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
5926 			{
5927 				if (ni->proto->primindex != 0) continue;
5928 				if (!insamecellgrp(ni->proto, np)) continue;
5929 				if (ni->proto != np)
5930 				{
5931 					if (ni->proto->cellview != el_iconview) continue;
5932 					if (iconview(np) != ni->proto) continue;
5933 				}
5934 
5935 				/* ensure that this node matches the updated parameter list */
5936 				for(i=0; i<ni->numvar; i++)
5937 				{
5938 					var = &ni->firstvar[i];
5939 					if (TDGETISPARAM(var->textdescript) == 0) continue;
5940 					fvar = NOVARIABLE;
5941 					for(j=0; j<np->numvar; j++)
5942 					{
5943 						fvar = &np->firstvar[j];
5944 						if (TDGETISPARAM(fvar->textdescript) == 0) continue;
5945 						if (namesame(makename(var->key), makename(fvar->key)) == 0) break;
5946 					}
5947 					if (j >= np->numvar)
5948 					{
5949 						/* this node's parameter is no longer on the cell: delete from instance */
5950 						startobjectchange((INTBIG)ni, VNODEINST);
5951 						(void)delvalkey((INTBIG)ni, VNODEINST, var->key);
5952 						endobjectchange((INTBIG)ni, VNODEINST);
5953 						i--;
5954 					} else
5955 					{
5956 						/* this node's parameter is still on the cell: make sure units are OK */
5957 						if (TDGETUNITS(var->textdescript) != TDGETUNITS(fvar->textdescript))
5958 						{
5959 							startobjectchange((INTBIG)ni, VNODEINST);
5960 							TDCOPY(descript, var->textdescript);
5961 							TDSETUNITS(descript, TDGETUNITS(fvar->textdescript));
5962 							modifydescript((INTBIG)ni, VNODEINST, var, descript);
5963 							endobjectchange((INTBIG)ni, VNODEINST);
5964 						}
5965 
5966 						/* make sure visibility is OK */
5967 						if (TDGETINTERIOR(fvar->textdescript) != 0) var->type &= ~VDISPLAY; else
5968 							var->type |= VDISPLAY;
5969 					}
5970 				}
5971 				for(j=0; j<np->numvar; j++)
5972 				{
5973 					fvar = &np->firstvar[j];
5974 					if (TDGETISPARAM(fvar->textdescript) == 0) continue;
5975 					for(i=0; i<ni->numvar; i++)
5976 					{
5977 						var = &ni->firstvar[i];
5978 						if (TDGETISPARAM(var->textdescript) == 0) continue;
5979 						if (namesame(makename(var->key), makename(fvar->key)) == 0) break;
5980 					}
5981 					if (i >= ni->numvar)
5982 					{
5983 						/* this cell parameter is not on the node: add to instance */
5984 						us_addparameter(ni, fvar->key, fvar->addr, fvar->type, fvar->textdescript);
5985 					}
5986 				}
5987 			}
5988 		}
5989 	}
5990 
5991 	/* make sure all of this cell's parameters are valid */
5992 	for(j=0; j<np->numvar; j++)
5993 	{
5994 		fvar = &np->firstvar[j];
5995 		if (TDGETISPARAM(fvar->textdescript) == 0) continue;
5996 		if ((fvar->type&VDISPLAY) == 0)
5997 		{
5998 			fvar->type |= VDISPLAY;
5999 			us_drawcellvariable(fvar, np);
6000 		}
6001 	}
6002 	return(0);
6003 }
6004 
6005 /****************************** CHANGE DIALOG ******************************/
6006 
6007 /* Change */
6008 static DIALOGITEM us_changedialogitems[] =
6009 {
6010  /*  1 */ {0, {264,344,288,416}, BUTTON, N_("OK")},
6011  /*  2 */ {0, {264,248,288,320}, BUTTON, N_("Cancel")},
6012  /*  3 */ {0, {8,232,24,438}, RADIO, N_("Change selected ones only")},
6013  /*  4 */ {0, {56,232,72,438}, RADIO, N_("Change all in this cell")},
6014  /*  5 */ {0, {104,232,120,438}, RADIO, N_("Change all in all libraries")},
6015  /*  6 */ {0, {32,232,48,438}, RADIO, N_("Change all connected to this")},
6016  /*  7 */ {0, {8,8,264,223}, SCROLL, x_("")},
6017  /*  8 */ {0, {272,8,288,78}, MESSAGE, N_("Library:")},
6018  /*  9 */ {0, {272,80,288,218}, POPUP, x_("")},
6019  /* 10 */ {0, {212,232,228,438}, CHECK, N_("Ignore port names")},
6020  /* 11 */ {0, {236,232,252,438}, CHECK, N_("Allow missing ports")},
6021  /* 12 */ {0, {140,232,156,438}, CHECK, N_("Change nodes with arcs")},
6022  /* 13 */ {0, {164,232,180,438}, CHECK, N_("Show primitives")},
6023  /* 14 */ {0, {188,232,204,438}, CHECK, N_("Show cells")},
6024  /* 15 */ {0, {80,232,96,438}, RADIO, N_("Change all in this library")}
6025 };
6026 static DIALOG us_changedialog = {{50,75,347,523}, N_("Change Nodes and Arcs"), 0, 15, us_changedialogitems, 0, 0};
6027 
6028 static BOOLEAN us_onproto(PORTPROTO*, ARCPROTO*);
6029 
6030 /* special items for the "change" dialog: */
6031 #define DCHG_THISONLY       3		/* This only (radio) */
6032 #define DCHG_INCELL         4		/* In cell (radio) */
6033 #define DCHG_UNIVERSALLY    5		/* Universally (radio) */
6034 #define DCHG_CONNECTED      6		/* Connected (radio) */
6035 #define DCHG_ALTLIST        7		/* Alternate list (scroll) */
6036 #define DCHG_LIBRARY_L      8		/* Library label (stat text) */
6037 #define DCHG_LIBRARIES      9		/* Libraries (popup) */
6038 #define DCHG_IGNOREPORT    10		/* Ignore port names (check) */
6039 #define DCHG_ALLOWDELETION 11		/* Allow missing port (check) */
6040 #define DCHG_NODESANDARCS  12		/* Change nodes with arcs (check) */
6041 #define DCHG_SHOWPRIMS     13		/* Show primitive nodes (check) */
6042 #define DCHG_SHOWCELLS     14		/* Show cell nodes (check) */
6043 #define DCHG_INLIBRARY     15		/* In this library (radio) */
6044 
us_replacedlog(void)6045 INTBIG us_replacedlog(void)
6046 {
6047 	INTBIG i, itemHit, total, ac;
6048 	BOOLEAN loadarclist, loadnodelist;
6049 	static INTBIG changeextent = DCHG_THISONLY;
6050 	static INTBIG nodesandarcs = 0;
6051 	REGISTER ARCPROTO *ap;
6052 	REGISTER NODEPROTO *np;
6053 	REGISTER ARCINST *ai;
6054 	REGISTER NODEINST *ni;
6055 	REGISTER PORTPROTO *pp1, *pp2;
6056 	REGISTER LIBRARY *lib;
6057 	REGISTER GEOM **list, *firstgeom;
6058 	REGISTER CHAR **liblist;
6059 	CHAR *par[7], *newname;
6060 	REGISTER void *infstr;
6061 	REGISTER void *dia;
6062 
6063 	/* see what is highlighted */
6064 	list = us_gethighlighted(WANTNODEINST|WANTARCINST, 0, 0);
6065 	firstgeom = list[0];
6066 	if (firstgeom == NOGEOM) return(0);
6067 
6068 	/* display the change dialog box */
6069 	dia = DiaInitDialog(&us_changedialog);
6070 	if (dia == 0) return(0);
6071 	DiaInitTextDialog(dia, DCHG_ALTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
6072 		SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT);
6073 	liblist = 0;
6074 	us_curlib = el_curlib;
6075 	if (firstgeom->entryisnode)
6076 	{
6077 		loadnodelist = TRUE;
6078 		loadarclist = FALSE;
6079 		DiaUnDimItem(dia, DCHG_LIBRARY_L);
6080 		DiaUnDimItem(dia, DCHG_LIBRARIES);
6081 		DiaUnDimItem(dia, DCHG_IGNOREPORT);
6082 		DiaUnDimItem(dia, DCHG_ALLOWDELETION);
6083 		DiaUnDimItem(dia, DCHG_SHOWPRIMS);
6084 		DiaUnDimItem(dia, DCHG_SHOWCELLS);
6085 		ni = firstgeom->entryaddr.ni;
6086 		if (ni->proto->primindex == 0)
6087 		{
6088 			DiaSetControl(dia, DCHG_SHOWCELLS, 1);
6089 			us_curlib = ni->proto->lib;
6090 		} else
6091 		{
6092 			DiaSetControl(dia, DCHG_SHOWPRIMS, 1);
6093 		}
6094 		DiaSetControl(dia, DCHG_NODESANDARCS, 0);
6095 		DiaDimItem(dia, DCHG_NODESANDARCS);
6096 	} else
6097 	{
6098 		loadarclist = TRUE;
6099 		loadnodelist = FALSE;
6100 		DiaDimItem(dia, DCHG_LIBRARY_L);
6101 		DiaDimItem(dia, DCHG_LIBRARIES);
6102 		DiaDimItem(dia, DCHG_IGNOREPORT);
6103 		DiaDimItem(dia, DCHG_ALLOWDELETION);
6104 		DiaDimItem(dia, DCHG_SHOWPRIMS);
6105 		DiaDimItem(dia, DCHG_SHOWCELLS);
6106 		DiaUnDimItem(dia, DCHG_NODESANDARCS);
6107 		DiaSetControl(dia, DCHG_NODESANDARCS, nodesandarcs);
6108 	}
6109 	DiaSetControl(dia, changeextent, 1);
6110 
6111 	/* loop until done */
6112 	for(;;)
6113 	{
6114 		if (loadnodelist)
6115 		{
6116 			DiaDimItem(dia, DCHG_LIBRARY_L);
6117 			DiaDimItem(dia, DCHG_LIBRARIES);
6118 			DiaLoadTextDialog(dia, DCHG_ALTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
6119 			if (DiaGetControl(dia, DCHG_SHOWCELLS) != 0)
6120 			{
6121 				/* cell: only list other cells as replacements */
6122 				us_showoldversions = 1;
6123 				us_showcellibrarycells = 1;
6124 				us_showonlyrelevantcells = 0;
6125 				DiaLoadTextDialog(dia, DCHG_ALTLIST, us_oldcelltopofcells, us_oldcellnextcells,
6126 					DiaNullDlogDone, 0);
6127 				(void)us_setscrolltocurrentcell(DCHG_ALTLIST, TRUE, FALSE, FALSE, FALSE, dia);
6128 				DiaUnDimItem(dia, DCHG_LIBRARY_L);
6129 				DiaUnDimItem(dia, DCHG_LIBRARIES);
6130 				if (liblist != 0) efree((CHAR *)liblist);
6131 				liblist = us_makelibrarylist(&total, us_curlib, &i);
6132 				DiaSetPopup(dia, DCHG_LIBRARIES, total, liblist);
6133 				if (i >= 0) DiaSetPopupEntry(dia, DCHG_LIBRARIES, i);
6134 			}
6135 			if (DiaGetControl(dia, DCHG_SHOWPRIMS) != 0)
6136 			{
6137 				/* primitive: list primitives in this and the generic technology */
6138 				for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
6139 					DiaStuffLine(dia, DCHG_ALTLIST, np->protoname);
6140 				if (el_curtech != gen_tech)
6141 				{
6142 					DiaStuffLine(dia, DCHG_ALTLIST, x_("Generic:Universal-Pin"));
6143 					DiaStuffLine(dia, DCHG_ALTLIST, x_("Generic:Invisible-Pin"));
6144 					DiaStuffLine(dia, DCHG_ALTLIST, x_("Generic:Unrouted-Pin"));
6145 				}
6146 				DiaSelectLine(dia, DCHG_ALTLIST, 0);
6147 			}
6148 			loadnodelist = FALSE;
6149 		}
6150 		if (loadarclist)
6151 		{
6152 			/* load arcs in current technology, arc's technology, and generic technology */
6153 			DiaLoadTextDialog(dia, DCHG_ALTLIST, DiaNullDlogList, DiaNullDlogItem,
6154 				DiaNullDlogDone, -1);
6155 			ai = firstgeom->entryaddr.ai;
6156 			pp1 = ai->end[0].portarcinst->proto;
6157 			pp2 = ai->end[1].portarcinst->proto;
6158 			for(ap = el_curtech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
6159 			{
6160 				if (DiaGetControl(dia, DCHG_NODESANDARCS) == 0)
6161 				{
6162 					if (!us_onproto(pp1, ap)) continue;
6163 					if (!us_onproto(pp2, ap)) continue;
6164 				}
6165 				DiaStuffLine(dia, DCHG_ALTLIST, ap->protoname);
6166 			}
6167 			if (el_curtech != gen_tech)
6168 				for(ap = gen_tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
6169 			{
6170 				if (DiaGetControl(dia, DCHG_NODESANDARCS) == 0)
6171 				{
6172 					if (!us_onproto(pp1, ap)) continue;
6173 					if (!us_onproto(pp2, ap)) continue;
6174 				}
6175 				DiaStuffLine(dia, DCHG_ALTLIST, describearcproto(ap));
6176 			}
6177 			if (ai->proto->tech != el_curtech && ai->proto->tech != gen_tech)
6178 				for(ap = ai->proto->tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
6179 			{
6180 				if (DiaGetControl(dia, DCHG_NODESANDARCS) == 0)
6181 				{
6182 					if (!us_onproto(pp1, ap)) continue;
6183 					if (!us_onproto(pp2, ap)) continue;
6184 				}
6185 				DiaStuffLine(dia, DCHG_ALTLIST, describearcproto(ap));
6186 			}
6187 			DiaSelectLine(dia, DCHG_ALTLIST, 0);
6188 			loadarclist = FALSE;
6189 		}
6190 		itemHit = DiaNextHit(dia);
6191 		if (itemHit == OK || itemHit == CANCEL) break;
6192 		if (itemHit == DCHG_THISONLY || itemHit == DCHG_INCELL ||
6193 			itemHit == DCHG_UNIVERSALLY || itemHit == DCHG_CONNECTED ||
6194 			itemHit == DCHG_INLIBRARY)
6195 		{
6196 			changeextent = itemHit;
6197 			DiaSetControl(dia, DCHG_THISONLY, 0);
6198 			DiaSetControl(dia, DCHG_INCELL, 0);
6199 			DiaSetControl(dia, DCHG_INLIBRARY, 0);
6200 			DiaSetControl(dia, DCHG_UNIVERSALLY, 0);
6201 			DiaSetControl(dia, DCHG_CONNECTED, 0);
6202 			DiaSetControl(dia, itemHit, 1);
6203 			if (itemHit == DCHG_UNIVERSALLY)
6204 			{
6205 				if (!firstgeom->entryisnode)
6206 				{
6207 					if (DiaGetControl(dia, DCHG_NODESANDARCS) != 0)
6208 					{
6209 						DiaSetControl(dia, DCHG_NODESANDARCS, 0);
6210 						loadarclist = TRUE;
6211 					}
6212 					DiaDimItem(dia, DCHG_NODESANDARCS);
6213 				}
6214 			} else
6215 			{
6216 				if (!firstgeom->entryisnode)
6217 					DiaUnDimItem(dia, DCHG_NODESANDARCS);
6218 			}
6219 		}
6220 		if (itemHit == DCHG_IGNOREPORT || itemHit == DCHG_ALLOWDELETION ||
6221 			itemHit == DCHG_NODESANDARCS || itemHit == DCHG_SHOWCELLS ||
6222 			itemHit == DCHG_SHOWPRIMS)
6223 		{
6224 			i = 1-DiaGetControl(dia, itemHit);
6225 			DiaSetControl(dia, itemHit, i);
6226 			if (itemHit == DCHG_NODESANDARCS &&
6227 				!firstgeom->entryisnode)
6228 			{
6229 				loadarclist = TRUE;
6230 				nodesandarcs = i;
6231 			}
6232 			if (itemHit == DCHG_SHOWCELLS || itemHit == DCHG_SHOWPRIMS)
6233 				loadnodelist = TRUE;
6234 			continue;
6235 		}
6236 		if (itemHit == DCHG_LIBRARIES)
6237 		{
6238 			i = DiaGetPopupEntry(dia, DCHG_LIBRARIES);
6239 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
6240 				if (namesame(lib->libname, liblist[i]) == 0) break;
6241 			if (lib == NOLIBRARY) continue;
6242 			us_curlib = lib;
6243 			DiaLoadTextDialog(dia, DCHG_ALTLIST, us_oldcelltopofcells, us_oldcellnextcells,
6244 				DiaNullDlogDone, 0);
6245 			(void)us_setscrolltocurrentcell(DCHG_ALTLIST, TRUE, FALSE, FALSE, FALSE, dia);
6246 			continue;
6247 		}
6248 	}
6249 	if (itemHit != CANCEL)
6250 	{
6251 		ac = 0;
6252 		infstr = initinfstr();
6253 		if (us_curlib != el_curlib)
6254 		{
6255 			addstringtoinfstr(infstr, us_curlib->libname);
6256 			addtoinfstr(infstr, ':');
6257 		}
6258 		addstringtoinfstr(infstr, DiaGetScrollLine(dia, DCHG_ALTLIST, DiaGetCurLine(dia, DCHG_ALTLIST)));
6259 		(void)allocstring(&newname, returninfstr(infstr), el_tempcluster);
6260 		par[ac++] = newname;
6261 		if (DiaGetControl(dia, DCHG_INCELL) != 0) par[ac++] = x_("this-cell");
6262 		if (DiaGetControl(dia, DCHG_INLIBRARY) != 0) par[ac++] = x_("this-library");
6263 		if (DiaGetControl(dia, DCHG_UNIVERSALLY) != 0) par[ac++] = x_("universally");
6264 		if (DiaGetControl(dia, DCHG_CONNECTED) != 0) par[ac++] = x_("connected");
6265 		if (DiaGetControl(dia, DCHG_IGNOREPORT) != 0) par[ac++] = x_("ignore-port-names");
6266 		if (DiaGetControl(dia, DCHG_ALLOWDELETION) != 0) par[ac++] = x_("allow-missing-ports");
6267 		if (DiaGetControl(dia, DCHG_NODESANDARCS) != 0) par[ac++] = x_("nodes-too");
6268 		us_replace(ac, par);
6269 		efree((CHAR *)newname);
6270 	}
6271 	if (liblist != 0) efree((CHAR *)liblist);
6272 	DiaDoneDialog(dia);
6273 	return(0);
6274 }
6275 
6276 /*
6277  * helper routine to determine whether arcproto "ap" can connect to portproto "pp".
6278  * returns nonzero if so
6279  */
us_onproto(PORTPROTO * pp,ARCPROTO * ap)6280 BOOLEAN us_onproto(PORTPROTO *pp, ARCPROTO *ap)
6281 {
6282 	REGISTER INTBIG i;
6283 
6284 	for(i=0; pp->connects[i] != NOARCPROTO; i++)
6285 		if (pp->connects[i] == ap) return(TRUE);
6286 	return(FALSE);
6287 }
6288 
6289 /****************************** CHOICE DIALOGS ******************************/
6290 
6291 /* No/Yes */
6292 static DIALOGITEM us_noyesdialogitems[] =
6293 {
6294 /*  1 */ {0, {80,132,104,204}, BUTTON, N_("No")},
6295 /*  2 */ {0, {80,60,104,124}, BUTTON, N_("Yes")},
6296 /*  3 */ {0, {8,8,72,256}, MESSAGE, x_("")}
6297 };
6298 static DIALOG us_noyesdialog = {{50,75,163,341}, N_("Warning"), 0, 3, us_noyesdialogitems, 0, 0};
6299 
6300 /* special items for "no/yes" dialog ("no" is default): */
6301 #define DNOY_NO      1		/* No (button) */
6302 #define DNOY_YES     2		/* Yes (button) */
6303 #define DNOY_MESSAGE 3		/* Message (stat text) */
6304 
us_noyesdlog(CHAR * prompt,CHAR * paramstart[])6305 INTBIG us_noyesdlog(CHAR *prompt, CHAR *paramstart[])
6306 {
6307 	INTBIG itemHit, oldplease;
6308 	REGISTER void *dia;
6309 
6310 	/* display the no/yes dialog box */
6311 	dia = DiaInitDialog(&us_noyesdialog);
6312 	if (dia == 0) return(0);
6313 
6314 	/* load the message */
6315 	DiaSetText(dia, DNOY_MESSAGE, prompt);
6316 
6317 	/* loop until done */
6318 	oldplease = el_pleasestop;
6319 	for(;;)
6320 	{
6321 		itemHit = DiaNextHit(dia);
6322 		if (itemHit == DNOY_NO || itemHit == DNOY_YES) break;
6323 	}
6324 	el_pleasestop = oldplease;
6325 
6326 	if (itemHit == DNOY_NO) paramstart[0] = x_("no"); else
6327 		paramstart[0] = x_("yes");
6328 	DiaDoneDialog(dia);
6329 	return(1);
6330 }
6331 
6332 /* Yes/No */
6333 static DIALOGITEM us_yesnodialogitems[] =
6334 {
6335 /*  1 */ {0, {64,156,88,228}, BUTTON, N_("Yes")},
6336 /*  2 */ {0, {64,68,88,140}, BUTTON, N_("No")},
6337 /*  3 */ {0, {6,15,54,279}, MESSAGE, x_("")}
6338 };
6339 static DIALOG us_yesnodialog = {{50,75,150,369}, N_("Warning"), 0, 3, us_yesnodialogitems, 0, 0};
6340 
6341 /* special items for "yes/no" dialog ("yes" is default): */
6342 #define DYNO_YES     1		/* Yes (button) */
6343 #define DYNO_NO      2		/* No (button) */
6344 #define DYNO_MESSAGE 3		/* Message (stat text) */
6345 
us_yesnodlog(CHAR * prompt,CHAR * paramstart[])6346 INTBIG us_yesnodlog(CHAR *prompt, CHAR *paramstart[])
6347 {
6348 	INTBIG itemHit, oldplease;
6349 	REGISTER void *dia;
6350 
6351 	/* display the yes/no dialog box */
6352 	dia = DiaInitDialog(&us_yesnodialog);
6353 	if (dia == 0) return(0);
6354 
6355 	/* load the message */
6356 	DiaSetText(dia, DYNO_MESSAGE, prompt);
6357 
6358 	/* loop until done */
6359 	oldplease = el_pleasestop;
6360 	for(;;)
6361 	{
6362 		itemHit = DiaNextHit(dia);
6363 		if (itemHit == DYNO_YES || itemHit == DYNO_NO) break;
6364 	}
6365 	el_pleasestop = oldplease;
6366 
6367 	if (itemHit == DYNO_YES) paramstart[0] = x_("yes"); else paramstart[0] = x_("no");
6368 	DiaDoneDialog(dia);
6369 	return(1);
6370 }
6371 
6372 /* Prompt: No/Yes/Always */
6373 static DIALOGITEM us_noyesalwaysdialogitems[] =
6374 {
6375 /*  1 */ {0, {64,168,88,248}, BUTTON, N_("No")},
6376 /*  2 */ {0, {64,8,88,88}, BUTTON, N_("Yes")},
6377 /*  3 */ {0, {124,88,148,168}, BUTTON, N_("Always")},
6378 /*  4 */ {0, {8,8,56,248}, MESSAGE, N_("Allow this?")},
6379 /*  5 */ {0, {100,8,116,248}, MESSAGE, N_("Click \"Always\" to disable the lock")}
6380 };
6381 static DIALOG us_noyesalwaysdialog = {{75,75,232,332}, N_("Allow this change?"), 0, 5, us_noyesalwaysdialogitems, 0, 0};
6382 
6383 /* special items for "no/yes/always" dialog ("no" is default): */
6384 #define DYNA_NO      1		/* No (button) */
6385 #define DYNA_YES     2		/* Yes (button) */
6386 #define DYNA_ALWAYS  3		/* Always (button) */
6387 #define DYNA_MESSAGE 4		/* Message (stat text) */
6388 
us_noyesalwaysdlog(CHAR * prompt,CHAR * paramstart[])6389 INTBIG us_noyesalwaysdlog(CHAR *prompt, CHAR *paramstart[])
6390 {
6391 	REGISTER INTBIG itemHit;
6392 	REGISTER void *dia;
6393 
6394 	dia = DiaInitDialog(&us_noyesalwaysdialog);
6395 	if (dia == 0) return(0);
6396 	DiaSetText(dia, DYNA_MESSAGE, prompt);
6397 	for(;;)
6398 	{
6399 		itemHit = DiaNextHit(dia);
6400 		if (itemHit == DYNA_NO || itemHit == DYNA_YES || itemHit == DYNA_ALWAYS) break;
6401 	}
6402 	DiaDoneDialog(dia);
6403 	if (itemHit == DYNA_NO) paramstart[0] = x_("no"); else
6404 		if (itemHit == DYNA_YES) paramstart[0] = x_("yes"); else
6405 			paramstart[0] = x_("always");
6406 	return(1);
6407 }
6408 
6409 /* Prompt: No/Yes/Cancel */
6410 static DIALOGITEM us_noyescanceldialogitems[] =
6411 {
6412  /*  1 */ {0, {80,108,104,188}, BUTTON, N_("No")},
6413  /*  2 */ {0, {80,12,104,92}, BUTTON, N_("Cancel")},
6414  /*  3 */ {0, {80,204,104,284}, BUTTON, N_("Yes")},
6415  /*  4 */ {0, {8,8,72,284}, MESSAGE, x_("")}
6416 };
6417 static DIALOG us_noyescanceldialog = {{75,75,188,368}, N_("Allow this change?"), 0, 4, us_noyescanceldialogitems, 0, 0};
6418 
6419 /* special items for "no/yes/cancel" dialog ("no" is default): */
6420 #define DYNC_NO      1		/* No (button) */
6421 #define DYNC_CANCEL  2		/* Cancel (button) */
6422 #define DYNC_YES     3		/* Yes (button) */
6423 #define DYNC_MESSAGE 4		/* Message (stat text) */
6424 
us_noyescanceldlog(CHAR * prompt,CHAR * paramstart[])6425 INTBIG us_noyescanceldlog(CHAR *prompt, CHAR *paramstart[])
6426 {
6427 	REGISTER INTBIG itemHit;
6428 	REGISTER void *dia;
6429 
6430 	dia = DiaInitDialog(&us_noyescanceldialog);
6431 	if (dia == 0) return(0);
6432 	DiaSetText(dia, DYNC_MESSAGE, prompt);
6433 	for(;;)
6434 	{
6435 		itemHit = DiaNextHit(dia);
6436 		if (itemHit == DYNC_NO || itemHit == DYNC_YES || itemHit == DYNC_CANCEL) break;
6437 	}
6438 	DiaDoneDialog(dia);
6439 	if (itemHit == DYNC_NO) paramstart[0] = x_("no"); else
6440 		if (itemHit == DYNC_YES) paramstart[0] = x_("yes"); else
6441 			paramstart[0] = x_("cancel");
6442 	return(1);
6443 }
6444 
6445 /* Prompt: OK */
6446 static DIALOGITEM us_okmessagedialogitems[] =
6447 {
6448 /*  1 */ {0, {72,64,96,144}, BUTTON, N_("OK")},
6449 /*  2 */ {0, {8,8,56,212}, MESSAGE, x_("")}
6450 };
6451 static DIALOG us_okmessagedialog = {{75,75,180,296}, 0, 0, 2, us_okmessagedialogitems, 0, 0};
6452 
6453 /* special items for "OK prompt" dialog: */
6454 #define DMSG_MESSAGE 2		/* Message (stat text) */
6455 
DiaMessageInDialog(CHAR * message,...)6456 void DiaMessageInDialog(CHAR *message, ...)
6457 {
6458 	va_list ap;
6459 	CHAR line[1000];
6460 	INTBIG itemHit;
6461 	REGISTER void *dia;
6462 
6463 	/* display the message dialog box */
6464 	dia = DiaInitDialog(&us_okmessagedialog);
6465 	if (dia == 0) return;
6466 
6467 	/* put the message in it */
6468 	var_start(ap, message);
6469 	evsnprintf(line, 1000, message, ap);
6470 	va_end(ap);
6471 	DiaSetText(dia, DMSG_MESSAGE, line);
6472 
6473 	/* loop until done */
6474 	for(;;)
6475 	{
6476 		itemHit = DiaNextHit(dia);
6477 		if (itemHit == OK) break;
6478 	}
6479 	DiaDoneDialog(dia);
6480 }
6481 
6482 /****************************** COLOR OPTIONS DIALOG ******************************/
6483 
6484 #define DEGTORAD    (EPI/180.0)
6485 #define INTENSITYDIVISIONS 20
6486 #define WHEELRADIUS        96
6487 #define WHEELEDGE          (WHEELRADIUS + WHEELRADIUS/16)
6488 
6489 /* Color Mixing */
6490 static DIALOGITEM us_colormixdialogitems[] =
6491 {
6492  /*  1 */ {0, {212,400,236,468}, BUTTON, N_("OK")},
6493  /*  2 */ {0, {212,320,236,388}, BUTTON, N_("Cancel")},
6494  /*  3 */ {0, {276,8,292,24}, USERDRAWN, x_("")},
6495  /*  4 */ {0, {276,36,292,472}, RADIO, N_("Entry")},
6496  /*  5 */ {0, {296,8,312,24}, USERDRAWN, x_("")},
6497  /*  6 */ {0, {296,36,312,472}, RADIO, N_("Entry")},
6498  /*  7 */ {0, {316,8,332,24}, USERDRAWN, x_("")},
6499  /*  8 */ {0, {316,36,332,472}, RADIO, N_("Entry")},
6500  /*  9 */ {0, {336,8,352,24}, USERDRAWN, x_("")},
6501  /* 10 */ {0, {336,36,352,472}, RADIO, N_("Entry")},
6502  /* 11 */ {0, {356,8,372,24}, USERDRAWN, x_("")},
6503  /* 12 */ {0, {356,36,372,472}, RADIO, N_("Entry")},
6504  /* 13 */ {0, {376,8,392,24}, USERDRAWN, x_("")},
6505  /* 14 */ {0, {376,36,392,472}, RADIO, N_("Entry")},
6506  /* 15 */ {0, {396,8,412,24}, USERDRAWN, x_("")},
6507  /* 16 */ {0, {396,36,412,472}, RADIO, N_("Entry")},
6508  /* 17 */ {0, {416,8,432,24}, USERDRAWN, x_("")},
6509  /* 18 */ {0, {416,36,432,472}, RADIO, N_("Entry")},
6510  /* 19 */ {0, {436,8,452,24}, USERDRAWN, x_("")},
6511  /* 20 */ {0, {436,36,452,472}, RADIO, N_("Entry")},
6512  /* 21 */ {0, {456,8,472,24}, USERDRAWN, x_("")},
6513  /* 22 */ {0, {456,36,472,472}, RADIO, N_("Entry")},
6514  /* 23 */ {0, {476,8,492,24}, USERDRAWN, x_("")},
6515  /* 24 */ {0, {476,36,492,472}, RADIO, N_("Entry")},
6516  /* 25 */ {0, {496,8,512,24}, USERDRAWN, x_("")},
6517  /* 26 */ {0, {496,36,512,472}, RADIO, N_("Entry")},
6518  /* 27 */ {0, {516,8,532,24}, USERDRAWN, x_("")},
6519  /* 28 */ {0, {516,36,532,472}, RADIO, N_("Entry")},
6520  /* 29 */ {0, {536,8,552,24}, USERDRAWN, x_("")},
6521  /* 30 */ {0, {536,36,552,472}, RADIO, N_("Entry")},
6522  /* 31 */ {0, {556,8,572,24}, USERDRAWN, x_("")},
6523  /* 32 */ {0, {556,36,572,472}, RADIO, N_("Entry")},
6524  /* 33 */ {0, {576,8,592,24}, USERDRAWN, x_("")},
6525  /* 34 */ {0, {576,36,592,472}, RADIO, N_("Entry")},
6526  /* 35 */ {0, {32,8,244,220}, USERDRAWN, x_("")},
6527  /* 36 */ {0, {32,228,244,298}, USERDRAWN, x_("")},
6528  /* 37 */ {0, {8,16,24,144}, MESSAGE, N_("Hue/Saturation:")},
6529  /* 38 */ {0, {8,228,24,308}, MESSAGE, N_("Intensity:")},
6530  /* 39 */ {0, {252,160,268,396}, POPUP, x_("")},
6531  /* 40 */ {0, {36,304,52,388}, MESSAGE, N_("Red:")},
6532  /* 41 */ {0, {60,304,76,388}, MESSAGE, N_("Green:")},
6533  /* 42 */ {0, {84,304,100,388}, MESSAGE, N_("Blue:")},
6534  /* 43 */ {0, {36,393,52,457}, EDITTEXT, x_("")},
6535  /* 44 */ {0, {60,393,76,457}, EDITTEXT, x_("")},
6536  /* 45 */ {0, {84,393,100,457}, EDITTEXT, x_("")},
6537  /* 46 */ {0, {252,8,268,148}, MESSAGE, N_("Colors being edited:")},
6538  /* 47 */ {0, {176,304,200,472}, BUTTON, N_("Set Transparent Layers")},
6539  /* 48 */ {0, {116,304,132,388}, MESSAGE, N_("Opacity:")},
6540  /* 49 */ {0, {140,304,156,388}, MESSAGE, N_("Foreground:")},
6541  /* 50 */ {0, {116,393,132,457}, EDITTEXT, x_("")},
6542  /* 51 */ {0, {140,393,156,457}, POPUP, x_("")}
6543 };
6544 static DIALOG us_colormixdialog = {{75,75,676,557}, N_("Color Mixing"), 0, 51, us_colormixdialogitems, 0, 0};
6545 
6546 /* special items for the "Color Mixing" dialog: */
6547 #define DCLR_FIRSTPATCH     3	/* first color patch for palette (user) */
6548 #define DCLR_FIRSTBUTTON    4	/* first button for palette (user) */
6549 #define DCLR_LASTBUTTON    34	/* last button for palette (user) */
6550 #define DCLR_HUESAT        35	/* Hue/Saturation wheel (user) */
6551 #define DCLR_INTENSITY     36	/* Intensity slider (user) */
6552 #define DCLR_PALETTES      39	/* palettes (popup) */
6553 #define DCLR_REDVAL        43	/* red (edit text) */
6554 #define DCLR_GREENVAL      44	/* green (edit text) */
6555 #define DCLR_BLUEVAL       45	/* blue (edit text) */
6556 #define DCLR_COMPPRIMARY   47	/* Compute from primaries (button) */
6557 #define DCLR_OPACITYVAL_L  48	/* opacity label (stat text) */
6558 #define DCLR_FOREGROUND_L  49	/* foreground label (stat text) */
6559 #define DCLR_OPACITYVAL    50	/* opacity (edit text) */
6560 #define DCLR_FOREGROUND    51	/* foreground (popup) */
6561 
6562 static INTBIG  us_colormixredmap[256], us_colormixgreenmap[256], us_colormixbluemap[256];
6563 static INTBIG  us_colormixindex[16];
6564 static INTBIG  us_colormixcurindex;
6565 static INTBIG  us_colormixlayercount;
6566 static INTBIG  us_colormixcurbank;
6567 static CHAR  **us_colormixlayernames;
6568 static BOOLEAN us_colormixingprint;
6569 static INTBIG *us_colormixlayerprintcolordata;
6570 static float   us_colormixtheta, us_colormixr, us_colormixinten;
6571 static CHAR   *us_colormixnames[5];
6572 
6573 static void    us_colormixreload(void *dia);
6574 static CHAR   *us_colormixentryname(CHAR *overlayernames[], INTBIG ind);
6575 static void    us_colormixbuildindex(INTBIG layer1, INTBIG layer2, INTBIG layer3, INTBIG layer4, INTBIG layer5);
6576 static void    us_colormixdrawpalette(RECTAREA *ra, void *dia);
6577 static void    us_colormixtogglemarker(void *dia);
6578 static void    us_colormixdrawsquare(INTBIG sindex, void *dia);
6579 static void    us_colormixmergecolor(INTBIG r1, INTBIG g1, INTBIG b1, INTBIG r2, INTBIG g2, INTBIG b2,
6580 				INTBIG *ro, INTBIG *go, INTBIG *bo);
6581 static void    us_colormixsmoothcolors(void);
6582 static BOOLEAN us_colormixsetcolor(void *dia, INTBIG r, INTBIG g, INTBIG b);
6583 
6584 /*
6585  * Routine to do color mixing.  The current color map is mixed, and the names of the transparent
6586  * layers are in "overlayernames".  In addition, print colors are mixed for the "layercount" layers
6587  * whose names are in "layernames" and whose data is in "printcolors".  The array "printcolors" has
6588  * 5 entries per color: the first 3 are the R/G/B; number 4 is the opacity (a fractional value from 0
6589  * to 1, which means from 0 to WHOLE); number 5 is the foreground factor (0 for off, 1 for on).
6590  * Returns TRUE if something changed; FALSE if nothing changed or it was cancelled.
6591  */
us_colormixdlog(CHAR * overlayernames[],INTBIG layercount,CHAR ** layernames,INTBIG * printcolors)6592 BOOLEAN us_colormixdlog(CHAR *overlayernames[], INTBIG layercount, CHAR **layernames, INTBIG *printcolors)
6593 {
6594 	REGISTER INTBIG itemHit, i, cx, cy, numpalettes, opa, fore;
6595 	INTBIG x, y, r, g, b;
6596 	BOOLEAN colorchanged;
6597 	REGISTER VARIABLE *varred, *vargreen, *varblue;
6598 	RECTAREA ra;
6599 	REGISTER void *dia, *infstr;
6600 	CHAR **palettelist, *transstr[2];
6601 
6602 	varred = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER|VISARRAY, us_colormap_red_key);
6603 	vargreen = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER|VISARRAY, us_colormap_green_key);
6604 	varblue = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER|VISARRAY, us_colormap_blue_key);
6605 	if (varred == NOVARIABLE || vargreen == NOVARIABLE || varblue == NOVARIABLE) return(FALSE);
6606 	for(i=0; i<256; i++)
6607 	{
6608 		us_colormixredmap[i] = ((INTBIG *)varred->addr)[i];
6609 		us_colormixgreenmap[i] = ((INTBIG *)vargreen->addr)[i];
6610 		us_colormixbluemap[i] = ((INTBIG *)varblue->addr)[i];
6611 	}
6612 	us_colormixlayercount = layercount;
6613 	us_colormixlayernames = layernames;
6614 	us_colormixlayerprintcolordata = printcolors;
6615 
6616 	/* display the color mixing dialog box */
6617 	dia = DiaInitDialog(&us_colormixdialog);
6618 	if (dia == 0) return(FALSE);
6619 	numpalettes = 7 + (layercount+15)/16;
6620 	palettelist = (CHAR **)emalloc(numpalettes * (sizeof (CHAR *)), el_tempcluster);
6621 	if (palettelist == 0) return(FALSE);
6622 	palettelist[0] = _("All transparent layers");
6623 	palettelist[1] = _("Special colors");
6624 	for(i=0; i<5; i++)
6625 	{
6626 		us_colormixnames[i] = overlayernames[i];
6627 		infstr = initinfstr();
6628 		formatinfstr(infstr, _("Transparent layer %ld: %s"), i+1, overlayernames[i]);
6629 		(void)allocstring(&palettelist[i+2], returninfstr(infstr), el_tempcluster);
6630 	}
6631 	for(i=7; i<numpalettes; i++)
6632 	{
6633 		infstr = initinfstr();
6634 		formatinfstr(infstr, _("Print layers, bank %ld"), i-6);
6635 		(void)allocstring(&palettelist[i], returninfstr(infstr), el_tempcluster);
6636 	}
6637 	DiaSetPopup(dia, DCLR_PALETTES, numpalettes, palettelist);
6638 	us_colormixcurbank = 0;
6639 	DiaSetPopupEntry(dia, DCLR_PALETTES, us_colormixcurbank);
6640 	transstr[0] = _("Off");
6641 	transstr[1] = _("On");
6642 	DiaSetPopup(dia, DCLR_FOREGROUND, 2, transstr);
6643 	us_colormixcurindex = 0;
6644 	DiaSetControl(dia, DCLR_FIRSTBUTTON, 1);
6645 	us_colormixdrawpalette(&ra, dia);
6646 	DiaRedispRoutine(dia, DCLR_HUESAT, us_colormixdrawpalette);
6647 	us_colormixingprint = FALSE;
6648 	DiaDimItem(dia, DCLR_OPACITYVAL);
6649 	DiaDimItem(dia, DCLR_OPACITYVAL_L);
6650 	DiaDimItem(dia, DCLR_FOREGROUND);
6651 	DiaDimItem(dia, DCLR_FOREGROUND_L);
6652 
6653 	/* loop until done */
6654 	colorchanged = FALSE;
6655 	for(;;)
6656 	{
6657 		itemHit = DiaNextHit(dia);
6658 		if (itemHit == OK || itemHit == CANCEL) break;
6659 		if (itemHit >= DCLR_FIRSTPATCH && itemHit <= DCLR_LASTBUTTON)
6660 		{
6661 			/* hit on one of the 16 colors */
6662 			us_colormixtogglemarker(dia);
6663 			for(i=DCLR_FIRSTBUTTON; i<=DCLR_LASTBUTTON; i += 2) DiaSetControl(dia, i, 0);
6664 			i = (itemHit + 1) / 2 * 2;
6665 			DiaSetControl(dia, i, 1);
6666 			us_colormixcurindex = (itemHit-DCLR_FIRSTPATCH)/2;
6667 			us_colormixdrawsquare(us_colormixcurindex, dia);
6668 			us_colormixtogglemarker(dia);
6669 			continue;
6670 		}
6671 		if (itemHit == DCLR_PALETTES)
6672 		{
6673 			/* changed the set of colors */
6674 			us_colormixtogglemarker(dia);
6675 			us_colormixcurbank = DiaGetPopupEntry(dia, DCLR_PALETTES);
6676 			us_colormixcurindex = 0;
6677 			for(i=DCLR_FIRSTBUTTON; i<=DCLR_LASTBUTTON; i += 2) DiaSetControl(dia, i, 0);
6678 			DiaSetControl(dia, DCLR_FIRSTBUTTON, 1);
6679 			us_colormixreload(dia);
6680 			us_colormixtogglemarker(dia);
6681 			continue;
6682 		}
6683 		if (itemHit == DCLR_HUESAT)
6684 		{
6685 			/* hit in the hue/saturation wheel */
6686 			DiaGetMouse(dia, &x, &y);
6687 			DiaItemRect(dia, DCLR_HUESAT, &ra);
6688 			cx = (ra.left + ra.right) / 2;
6689 			cy = (ra.top + ra.bottom) / 2;
6690 			us_colormixtogglemarker(dia);
6691 			us_colormixtheta = (float)((figureangle(cx, cy, x, y) + 5) / 10);
6692 			if (us_colormixtheta < 0.0) us_colormixtheta += 360.0;
6693 			us_colormixr = (float)sqrt((float)((y-cy)*(y-cy) + (x-cx)*(x-cx)));
6694 			if (us_colormixr > WHEELEDGE) us_colormixr = WHEELEDGE;
6695 			us_hsvtorgb(us_colormixtheta / 360.0f, us_colormixr / WHEELEDGE, us_colormixinten, &r,
6696 				&g, &b);
6697 			if (us_colormixsetcolor(dia, r, g, b))
6698 			{
6699 				colorchanged = TRUE;
6700 				us_colormixdrawsquare(us_colormixcurindex, dia);
6701 			}
6702 			us_colormixtogglemarker(dia);
6703 			continue;
6704 		}
6705 		if (itemHit == DCLR_INTENSITY)
6706 		{
6707 			/* hit in the intensity slider */
6708 			DiaGetMouse(dia, &x, &y);
6709 			DiaItemRect(dia, DCLR_INTENSITY, &ra);
6710 			cx = (ra.left + ra.right) / 2;
6711 			cy = (ra.top + ra.bottom) / 2;
6712 			us_colormixtogglemarker(dia);
6713 			us_colormixinten = (float)(ra.bottom - y) / (float)(ra.bottom - ra.top);
6714 			us_hsvtorgb(us_colormixtheta / 360.0f, us_colormixr / WHEELEDGE, us_colormixinten, &r,
6715 				&g, &b);
6716 			if (us_colormixsetcolor(dia, r, g, b))
6717 			{
6718 				colorchanged = TRUE;
6719 				us_colormixdrawsquare(us_colormixcurindex, dia);
6720 			}
6721 			us_colormixtogglemarker(dia);
6722 			continue;
6723 		}
6724 		if (itemHit == DCLR_REDVAL || itemHit == DCLR_GREENVAL ||
6725 			itemHit == DCLR_BLUEVAL)
6726 		{
6727 			r = myatoi(DiaGetText(dia, DCLR_REDVAL));
6728 			g = myatoi(DiaGetText(dia, DCLR_GREENVAL));
6729 			b = myatoi(DiaGetText(dia, DCLR_BLUEVAL));
6730 			us_colormixtogglemarker(dia);
6731 			if (us_colormixsetcolor(dia, r, g, b))
6732 			{
6733 				colorchanged = TRUE;
6734 				us_colormixdrawsquare(us_colormixcurindex, dia);
6735 			}
6736 			us_colormixtogglemarker(dia);
6737 			continue;
6738 		}
6739 		if (itemHit == DCLR_OPACITYVAL || itemHit == DCLR_FOREGROUND)
6740 		{
6741 			if (us_colormixcurbank < 7) continue;
6742 			opa = atofr(DiaGetText(dia, DCLR_OPACITYVAL));
6743 			fore = DiaGetPopupEntry(dia, DCLR_FOREGROUND);
6744 			i = (us_colormixcurbank-7)*16+us_colormixcurindex;
6745 			if (opa == us_colormixlayerprintcolordata[i*5+3] &&
6746 				fore == us_colormixlayerprintcolordata[i*5+4]) continue;
6747 			us_colormixlayerprintcolordata[i*5+3] = opa;
6748 			us_colormixlayerprintcolordata[i*5+4] = fore;
6749 			colorchanged = TRUE;
6750 			continue;
6751 		}
6752 
6753 		if (itemHit == DCLR_COMPPRIMARY)
6754 		{
6755 			/* recompute colors based on layer depth of primaries */
6756 			us_colormixtogglemarker(dia);
6757 			us_colormixsmoothcolors();
6758 			us_colormixreload(dia);
6759 			us_colormixtogglemarker(dia);
6760 			colorchanged = TRUE;
6761 			continue;
6762 		}
6763 	}
6764 
6765 	if (itemHit == CANCEL) colorchanged = FALSE;
6766 	if (colorchanged)
6767 	{
6768 		/* propagate highlight and grid colors to every appropriate entry */
6769 		for(i=0; i<256; i++)
6770 		{
6771 			if ((i&LAYERG) != 0)
6772 			{
6773 				us_colormixredmap[i] = us_colormixredmap[LAYERG];
6774 				us_colormixgreenmap[i] = us_colormixgreenmap[LAYERG];
6775 				us_colormixbluemap[i] = us_colormixbluemap[LAYERG];
6776 			}
6777 			if ((i&LAYERH) != 0)
6778 			{
6779 				us_colormixredmap[i] = us_colormixredmap[LAYERH];
6780 				us_colormixgreenmap[i] = us_colormixgreenmap[LAYERH];
6781 				us_colormixbluemap[i] = us_colormixbluemap[LAYERH];
6782 			}
6783 		}
6784 		startobjectchange((INTBIG)us_tool, VTOOL);
6785 		(void)setvalkey((INTBIG)us_tool, VTOOL, us_colormap_red_key, (INTBIG)us_colormixredmap,
6786 			VINTEGER|VISARRAY|(256<<VLENGTHSH));
6787 		(void)setvalkey((INTBIG)us_tool, VTOOL, us_colormap_green_key, (INTBIG)us_colormixgreenmap,
6788 			VINTEGER|VISARRAY|(256<<VLENGTHSH));
6789 		(void)setvalkey((INTBIG)us_tool, VTOOL, us_colormap_blue_key, (INTBIG)us_colormixbluemap,
6790 			VINTEGER|VISARRAY|(256<<VLENGTHSH));
6791 		endobjectchange((INTBIG)us_tool, VTOOL);
6792 	}
6793 	DiaDoneDialog(dia);
6794 	for(i=2; i<numpalettes; i++)
6795 		efree((CHAR *)palettelist[i]);
6796 	efree((CHAR *)palettelist);
6797 	return(colorchanged);
6798 }
6799 
us_colormixsetcolor(void * dia,INTBIG r,INTBIG g,INTBIG b)6800 BOOLEAN us_colormixsetcolor(void *dia, INTBIG r, INTBIG g, INTBIG b)
6801 {
6802 	REGISTER INTBIG i;
6803 	Q_UNUSED( dia );
6804 
6805 	if (us_colormixcurbank >= 7)
6806 	{
6807 		i = (us_colormixcurbank-7)*16+us_colormixcurindex;
6808 		if (r == us_colormixlayerprintcolordata[i*5] &&
6809 			g == us_colormixlayerprintcolordata[i*5+1] &&
6810 			b == us_colormixlayerprintcolordata[i*5+2]) return(FALSE);
6811 		us_colormixlayerprintcolordata[i*5] = r;
6812 		us_colormixlayerprintcolordata[i*5+1] = g;
6813 		us_colormixlayerprintcolordata[i*5+2] = b;
6814 	} else
6815 	{
6816 		if (r == us_colormixredmap[us_colormixindex[us_colormixcurindex]] &&
6817 			g == us_colormixgreenmap[us_colormixindex[us_colormixcurindex]] &&
6818 			b == us_colormixbluemap[us_colormixindex[us_colormixcurindex]]) return(FALSE);
6819 		us_colormixredmap[us_colormixindex[us_colormixcurindex]] = r;
6820 		us_colormixgreenmap[us_colormixindex[us_colormixcurindex]] = g;
6821 		us_colormixbluemap[us_colormixindex[us_colormixcurindex]] = b;
6822 	}
6823 	return(TRUE);
6824 }
6825 
6826 /*
6827  * Routine to rebuild the transparent layer interactions based on the single-transparent layer
6828  * colors.  All combinations of more than 1 transparent layer are derived automatically.
6829  */
us_colormixsmoothcolors(void)6830 void us_colormixsmoothcolors(void)
6831 {
6832 	INTBIG funct[5], height[5], bit[5], red[5], green[5], blue[5], fun,
6833 		r, g, b, i, j;
6834 	BOOLEAN gotcol;
6835 	CHAR *lname[5], *name;
6836 
6837 	/* get information about the current transparent layers */
6838 	for(i=0; i<5; i++) funct[i] = -1;
6839 	for(i=0; i<el_curtech->layercount; i++)
6840 	{
6841 		fun = layerfunction(el_curtech, i);
6842 		name = layername(el_curtech, i);
6843 		if ((fun&LFTRANS1) != 0 && funct[0] < 0) { funct[0] = fun;  lname[0] = name; }
6844 		if ((fun&LFTRANS2) != 0 && funct[1] < 0) { funct[1] = fun;  lname[1] = name; }
6845 		if ((fun&LFTRANS3) != 0 && funct[2] < 0) { funct[2] = fun;  lname[2] = name; }
6846 		if ((fun&LFTRANS4) != 0 && funct[3] < 0) { funct[3] = fun;  lname[3] = name; }
6847 		if ((fun&LFTRANS5) != 0 && funct[4] < 0) { funct[4] = fun;  lname[4] = name; }
6848 	}
6849 	bit[0] = LAYERT1;
6850 	bit[1] = LAYERT2;
6851 	bit[2] = LAYERT3;
6852 	bit[3] = LAYERT4;
6853 	bit[4] = LAYERT5;
6854 	for(i=0; i<5; i++)
6855 		height[i] = layerfunctionheight(funct[i]);
6856 
6857 	/* sort the layers by height */
6858 	j = 0;
6859 	while (j == 0)
6860 	{
6861 		j = 1;
6862 		for(i=1; i<5; i++)
6863 		{
6864 			if (height[i] <= height[i-1]) continue;
6865 			fun = height[i];  height[i] = height[i-1];  height[i-1] = fun;
6866 			fun = funct[i];   funct[i] = funct[i-1];    funct[i-1] = fun;
6867 			fun = bit[i];     bit[i] = bit[i-1];        bit[i-1] = fun;
6868 			j = 0;
6869 		}
6870 	}
6871 	for(i=0; i<5; i++)
6872 	{
6873 		red[i] = us_colormixredmap[bit[i]];
6874 		green[i] = us_colormixgreenmap[bit[i]];
6875 		blue[i] = us_colormixbluemap[bit[i]];
6876 	}
6877 
6878 	/* now reconstruct the colors */
6879 	for(i=0; i<256; i++)
6880 	{
6881 		if ((i&(LAYERH|LAYEROE|LAYERG)) != 0) continue;
6882 		gotcol = FALSE;
6883 		for(j=0; j<5; j++)
6884 		{
6885 			if ((i&bit[j]) == 0) continue;
6886 			if (!gotcol)
6887 			{
6888 				r = red[j];   g = green[j];   b = blue[j];
6889 				gotcol = TRUE;
6890 			} else
6891 			{
6892 				us_colormixmergecolor(r, g, b, red[j], green[j], blue[j], &r, &g, &b);
6893 			}
6894 		}
6895 		if (gotcol)
6896 		{
6897 			us_colormixredmap[i] = r;
6898 			us_colormixgreenmap[i] = g;
6899 			us_colormixbluemap[i] = b;
6900 		}
6901 	}
6902 }
6903 
6904 /*
6905  * Helper routine for "us_colormixsmoothcolors()" to do a vector-add of colors (r1,g1,b1)
6906  * and (r2,g2,b2) to produce the new color (ro,go,bo).
6907  */
us_colormixmergecolor(INTBIG r1,INTBIG g1,INTBIG b1,INTBIG r2,INTBIG g2,INTBIG b2,INTBIG * ro,INTBIG * go,INTBIG * bo)6908 void us_colormixmergecolor(INTBIG r1, INTBIG g1, INTBIG b1, INTBIG r2, INTBIG g2, INTBIG b2,
6909 	INTBIG *ro, INTBIG *go, INTBIG *bo)
6910 {
6911 	float f1[3], f2[3], f3[3];
6912 
6913 	f1[0] = r1 / 255.0f;
6914 	f1[1] = g1 / 255.0f;
6915 	f1[2] = b1 / 255.0f;
6916 	vectornormalize3d(f1);
6917 	vectormultiply3d(f1, 1.0f, f1);
6918 
6919 	f2[0] = r2 / 255.0f;
6920 	f2[1] = g2 / 255.0f;
6921 	f2[2] = b2 / 255.0f;
6922 	vectornormalize3d(f2);
6923 	vectormultiply3d(f2, 0.5f, f2);
6924 
6925 	vectoradd3d(f1, f2, f3);
6926 	vectornormalize3d(f3);
6927 
6928 	*ro = (INTBIG)(f3[0] * 255.0);
6929 	*go = (INTBIG)(f3[1] * 255.0);
6930 	*bo = (INTBIG)(f3[2] * 255.0);
6931 }
6932 
6933 /*
6934  * Routine to draw the hue/saturation wheel and the intensity slider
6935  */
us_colormixdrawpalette(RECTAREA * ra,void * dia)6936 void us_colormixdrawpalette(RECTAREA *ra, void *dia)
6937 {
6938 	Q_UNUSED( ra );
6939 	REGISTER INTBIG theta, inc, rr, cx, cy, i, col, spacing;
6940 	INTBIG r, g, b, x[4], y[4];
6941 	RECTAREA rect, stripe;
6942 	float intermed, intertwo;
6943 
6944 	/* draw hue/saturation wheel */
6945 	DiaItemRect(dia, DCLR_HUESAT, &rect);
6946 	cx = (rect.left + rect.right) / 2;
6947 	cy = (rect.top + rect.bottom) / 2;
6948 	for(theta=0; theta<360; theta+=60)
6949 	{
6950 		for(inc=0; inc<60; inc+=20)
6951 			for(rr = 0; rr < WHEELRADIUS/2; rr += WHEELRADIUS/8)
6952 		{
6953 			intermed = (float) theta + inc;
6954 			intertwo = (float) rr + WHEELRADIUS/8;
6955 			x[0] = (INTBIG)(((float)rr) * cos(intermed*DEGTORAD)) + cx;
6956 			y[0] = (INTBIG)(((float)rr) * sin(intermed*DEGTORAD)) + cy;
6957 			x[1] = (INTBIG)(intertwo * cos(intermed*DEGTORAD)) + cx;
6958 			y[1] = (INTBIG)(intertwo * sin(intermed*DEGTORAD)) + cy;
6959 			intermed += 21.0;
6960 			x[2] = (INTBIG)(intertwo * cos(intermed*DEGTORAD)) + cx;
6961 			y[2] = (INTBIG)(intertwo * sin(intermed*DEGTORAD)) + cy;
6962 			x[3] = (INTBIG)(((float)rr) * cos(intermed*DEGTORAD)) + cx;
6963 			y[3] = (INTBIG)(((float)rr) * sin(intermed*DEGTORAD)) + cy;
6964 			us_hsvtorgb(((float)(theta+inc+10)) / 360.0f,
6965 				((float)rr+WHEELRADIUS/16) / WHEELRADIUS, 1.0f, &r, &g, &b);
6966 			DiaFillPoly(dia, DCLR_HUESAT, x, y, 4, r, g, b);
6967 		}
6968 		for(inc=0; inc<60; inc+=10)
6969 			for(rr = WHEELRADIUS/8; rr < WHEELRADIUS; rr += WHEELRADIUS/8)
6970 		{
6971 			intermed = (float) theta + inc;
6972 			intertwo = (float) rr + WHEELRADIUS/8;
6973 			x[0] = (INTBIG)(((float)rr)* cos(intermed*DEGTORAD)) + cx;
6974 			y[0] = (INTBIG)(((float)rr)* sin(intermed*DEGTORAD)) + cy;
6975 			x[1] = (INTBIG)(intertwo * cos(intermed*DEGTORAD)) + cx;
6976 			y[1] = (INTBIG)(intertwo * sin(intermed*DEGTORAD)) + cy;
6977 			intermed += 12.0;
6978 			x[2] = (INTBIG)(intertwo * cos(intermed*DEGTORAD)) + cx;
6979 			y[2] = (INTBIG)(intertwo * sin(intermed*DEGTORAD)) + cy;
6980 			x[3] = (INTBIG)(((float)rr) * cos(intermed*DEGTORAD)) + cx;
6981 			y[3] = (INTBIG)(((float)rr) * sin(intermed*DEGTORAD)) + cy;
6982 			us_hsvtorgb(((float)(theta+inc+5)) / 360.0f,
6983 				((float)rr+WHEELRADIUS/16) / WHEELRADIUS, 1.0f, &r, &g, &b);
6984 			DiaFillPoly(dia, DCLR_HUESAT, x, y, 4, r, g, b);
6985 		}
6986 	}
6987 
6988 	/* draw the intensity slider */
6989 	DiaItemRect(dia, DCLR_INTENSITY, &rect);
6990 	rect.left--;   rect.right++;
6991 	rect.top--;    rect.bottom++;
6992 	DiaFrameRect(dia, DCLR_INTENSITY, &rect);
6993 	rect.left++;   rect.right--;
6994 	rect.top++;    rect.bottom--;
6995 	spacing = (rect.bottom - rect.top) / INTENSITYDIVISIONS;
6996 	for(i=0; i<INTENSITYDIVISIONS; i++)
6997 	{
6998 		stripe.left = rect.left;
6999 		stripe.right = rect.right;
7000 		stripe.top = (INTSML)(rect.bottom - (i+1)*spacing);
7001 		stripe.bottom = (INTSML)(rect.bottom - i*spacing);
7002 		col = i * 255 / INTENSITYDIVISIONS;
7003 		DiaDrawRect(dia, DCLR_INTENSITY, &stripe, col, col, col);
7004 	}
7005 
7006 	/* draw the current color marker */
7007 	us_colormixreload(dia);
7008 	us_colormixtogglemarker(dia);
7009 }
7010 
7011 /*
7012  * Routine to draw an "x" on the hue/saturation wheel and the intensity slider
7013  * to indicate the current color.
7014  */
us_colormixtogglemarker(void * dia)7015 void us_colormixtogglemarker(void *dia)
7016 {
7017 	REGISTER INTBIG r, g, b, cx, cy, x, y, i, index;
7018 	RECTAREA rect;
7019 
7020 	/* get the current color */
7021 	if (us_colormixcurbank >= 7)
7022 	{
7023 		i = (us_colormixcurbank-7)*16+us_colormixcurindex;
7024 		r = us_colormixlayerprintcolordata[i*5];
7025 		g = us_colormixlayerprintcolordata[i*5+1];
7026 		b = us_colormixlayerprintcolordata[i*5+2];
7027 	} else
7028 	{
7029 		index = us_colormixindex[us_colormixcurindex];
7030 		r = us_colormixredmap[index];
7031 		g = us_colormixgreenmap[index];
7032 		b = us_colormixbluemap[index];
7033 	}
7034 	us_rgbtohsv(r, g, b, &us_colormixtheta, &us_colormixr, &us_colormixinten);
7035 	us_colormixtheta *= 360.0;
7036 	us_colormixr *= WHEELEDGE;
7037 
7038 	/* show the position in the hue/saturation area */
7039 	DiaItemRect(dia, DCLR_HUESAT, &rect);
7040 	cx = (rect.left + rect.right) / 2;
7041 	cy = (rect.top + rect.bottom) / 2;
7042 	x = (INTBIG)(us_colormixr * cos(us_colormixtheta * DEGTORAD)) + cx;
7043 	y = (INTBIG)(us_colormixr * sin(us_colormixtheta * DEGTORAD)) + cy;
7044 	DiaDrawLine(dia, DCLR_HUESAT, x-5, y-5, x+5, y+5, DLMODEINVERT);
7045 	DiaDrawLine(dia, DCLR_HUESAT, x-5, y+5, x+5, y-5, DLMODEINVERT);
7046 
7047 	/* show the position in the intensity area */
7048 	DiaItemRect(dia, DCLR_INTENSITY, &rect);
7049 	cx = (rect.left + rect.right) / 2;
7050 	y = rect.bottom - (INTBIG)(us_colormixinten * (float)(rect.bottom - rect.top));
7051 	DiaDrawLine(dia, DCLR_INTENSITY, cx-5, y-5, cx+5, y+5, DLMODEINVERT);
7052 	DiaDrawLine(dia, DCLR_INTENSITY, cx-5, y+5, cx+5, y-5, DLMODEINVERT);
7053 }
7054 
7055 /*
7056  * Routine to reload the 16 color entries according to the selected palette set.
7057  */
us_colormixreload(void * dia)7058 void us_colormixreload(void *dia)
7059 {
7060 	INTBIG i;
7061 
7062 	if (us_colormixcurbank >= 7)
7063 	{
7064 		DiaUnDimItem(dia, DCLR_OPACITYVAL);
7065 		DiaUnDimItem(dia, DCLR_OPACITYVAL_L);
7066 		DiaUnDimItem(dia, DCLR_FOREGROUND);
7067 		DiaUnDimItem(dia, DCLR_FOREGROUND_L);
7068 		us_colormixingprint = TRUE;
7069 		for(i=0; i<16; i++)
7070 		{
7071 			us_colormixindex[i] = (us_colormixcurbank-7)*16+i;
7072 			if (us_colormixindex[i] >= us_colormixlayercount)
7073 			{
7074 				DiaSetText(dia, i*2+DCLR_FIRSTBUTTON, "");
7075 				us_colormixindex[i] = -1;
7076 			} else
7077 			{
7078 				DiaSetText(dia, i*2+DCLR_FIRSTBUTTON,
7079 					us_colormixlayernames[us_colormixindex[i]]);
7080 			}
7081 			if (i != us_colormixcurindex)
7082 				us_colormixdrawsquare(i, dia);
7083 		}
7084 		us_colormixdrawsquare(us_colormixcurindex, dia);
7085 		return;
7086 	}
7087 	us_colormixingprint = FALSE;
7088 	DiaDimItem(dia, DCLR_OPACITYVAL);
7089 	DiaDimItem(dia, DCLR_OPACITYVAL_L);
7090 	DiaDimItem(dia, DCLR_FOREGROUND);
7091 	DiaDimItem(dia, DCLR_FOREGROUND_L);
7092 	switch (us_colormixcurbank)
7093 	{
7094 		case 0:		/* all transparent layers */
7095 			us_colormixindex[0]  = ALLOFF;
7096 			us_colormixindex[1]  = LAYERT1;
7097 			us_colormixindex[2]  = LAYERT2;
7098 			us_colormixindex[3]  = LAYERT3;
7099 			us_colormixindex[4]  = LAYERT4;
7100 			us_colormixindex[5]  = LAYERT5;
7101 			us_colormixindex[6]  = LAYERT1 | LAYERT2;
7102 			us_colormixindex[7]  = LAYERT1 | LAYERT3;
7103 			us_colormixindex[8]  = LAYERT1 | LAYERT4;
7104 			us_colormixindex[9]  = LAYERT1 | LAYERT5;
7105 			us_colormixindex[10] = LAYERT2 | LAYERT3;
7106 			us_colormixindex[11] = LAYERT2 | LAYERT4;
7107 			us_colormixindex[12] = LAYERT2 | LAYERT5;
7108 			us_colormixindex[13] = LAYERT3 | LAYERT4;
7109 			us_colormixindex[14] = LAYERT3 | LAYERT5;
7110 			us_colormixindex[15] = LAYERT4 | LAYERT5;
7111 			break;
7112 		case 1:		/* special colors */
7113 			us_colormixindex[0]  = ALLOFF;
7114 			us_colormixindex[1]  = GRID;
7115 			us_colormixindex[2]  = HIGHLIT;
7116 			us_colormixindex[3]  = el_colcelltxt;
7117 			us_colormixindex[4]  = el_colcell;
7118 			us_colormixindex[5]  = el_colwinbor;
7119 			us_colormixindex[6]  = el_colhwinbor;
7120 			us_colormixindex[7]  = el_colmenbor;
7121 			us_colormixindex[8]  = el_colhmenbor;
7122 			us_colormixindex[9]  = el_colmentxt;
7123 			us_colormixindex[10] = el_colmengly;
7124 			us_colormixindex[11] = el_colcursor;
7125 			us_colormixindex[12] = 0354;
7126 			us_colormixindex[13] = 0364;
7127 			us_colormixindex[14] = 0374;
7128 			us_colormixindex[15] = ALLOFF;
7129 			break;
7130 		case 2:		/* the first transparent layer */
7131 			us_colormixbuildindex(LAYERT1, LAYERT2, LAYERT3, LAYERT4, LAYERT5);
7132 			break;
7133 		case 3:		/* the second transparent layer */
7134 			us_colormixbuildindex(LAYERT2, LAYERT1, LAYERT3, LAYERT4, LAYERT5);
7135 			break;
7136 		case 4:		/* the third transparent layer */
7137 			us_colormixbuildindex(LAYERT3, LAYERT1, LAYERT2, LAYERT4, LAYERT5);
7138 			break;
7139 		case 5:		/* the fourth transparent layer */
7140 			us_colormixbuildindex(LAYERT4, LAYERT1, LAYERT2, LAYERT3, LAYERT5);
7141 			break;
7142 		case 6:		/* the fifth transparent layer */
7143 			us_colormixbuildindex(LAYERT5, LAYERT1, LAYERT2, LAYERT3, LAYERT4);
7144 			break;
7145 	}
7146 	for(i=0; i<16; i++)
7147 	{
7148 		DiaSetText(dia, i*2+DCLR_FIRSTBUTTON,
7149 			us_colormixentryname(us_colormixnames, us_colormixindex[i]));
7150 		if (i != us_colormixcurindex)
7151 			us_colormixdrawsquare(i, dia);
7152 	}
7153 	us_colormixdrawsquare(us_colormixcurindex, dia);
7154 }
7155 
7156 /*
7157  * Routine to build the entries desired given the five layers "layer1-5".
7158  */
us_colormixbuildindex(INTBIG layer1,INTBIG layer2,INTBIG layer3,INTBIG layer4,INTBIG layer5)7159 void us_colormixbuildindex(INTBIG layer1, INTBIG layer2, INTBIG layer3, INTBIG layer4, INTBIG layer5)
7160 {
7161 	us_colormixindex[0]  = layer1;
7162 	us_colormixindex[1]  = layer1 | layer2;
7163 	us_colormixindex[2]  = layer1 |          layer3;
7164 	us_colormixindex[3]  = layer1 | layer2 | layer3;
7165 	us_colormixindex[4]  = layer1 |                   layer4;
7166 	us_colormixindex[5]  = layer1 | layer2 |          layer4;
7167 	us_colormixindex[6]  = layer1 |          layer3 | layer4;
7168 	us_colormixindex[7]  = layer1 | layer2 | layer3 | layer4;
7169 	us_colormixindex[8]  = layer1 |                            layer5;
7170 	us_colormixindex[9]  = layer1 | layer2 |                   layer5;
7171 	us_colormixindex[10] = layer1 |          layer3 |          layer5;
7172 	us_colormixindex[11] = layer1 | layer2 | layer3 |          layer5;
7173 	us_colormixindex[12] = layer1 |                   layer4 | layer5;
7174 	us_colormixindex[13] = layer1 | layer2 |          layer4 | layer5;
7175 	us_colormixindex[14] = layer1 |          layer3 | layer4 | layer5;
7176 	us_colormixindex[15] = layer1 | layer2 | layer3 | layer4 | layer5;
7177 }
7178 
7179 /*
7180  * Routine to redraw color square "sindex" from the current settings.
7181  */
us_colormixdrawsquare(INTBIG sindex,void * dia)7182 void us_colormixdrawsquare(INTBIG sindex, void *dia)
7183 {
7184 	RECTAREA rect;
7185 	REGISTER INTBIG r, g, b, i, index;
7186 	CHAR line[50];
7187 
7188 	DiaItemRect(dia, sindex*2+DCLR_FIRSTPATCH, &rect);
7189 	rect.left--;   rect.right++;
7190 	rect.top--;    rect.bottom++;
7191 	DiaFrameRect(dia, sindex*2+DCLR_FIRSTPATCH, &rect);
7192 	rect.left++;   rect.right--;
7193 	rect.top++;    rect.bottom--;
7194 
7195 	if (us_colormixcurbank >= 7)
7196 	{
7197 		i = (us_colormixcurbank-7)*16+sindex;
7198 		if (i >= us_colormixlayercount)
7199 		{
7200 			r = g = b = 255;
7201 		} else
7202 		{
7203 			r = us_colormixlayerprintcolordata[i*5];
7204 			g = us_colormixlayerprintcolordata[i*5+1];
7205 			b = us_colormixlayerprintcolordata[i*5+2];
7206 			estrcpy(line, frtoa(us_colormixlayerprintcolordata[i*5+3]));
7207 			DiaSetText(dia, DCLR_OPACITYVAL, line);
7208 			if (us_colormixlayerprintcolordata[i*5+4] != 0) DiaSetPopupEntry(dia, DCLR_FOREGROUND, 1); else
7209 				DiaSetPopupEntry(dia, DCLR_FOREGROUND, 0);
7210 		}
7211 	} else
7212 	{
7213 		index = us_colormixindex[sindex];
7214 		r = us_colormixredmap[index];
7215 		g = us_colormixgreenmap[index];
7216 		b = us_colormixbluemap[index];
7217 	}
7218 	DiaDrawRect(dia, sindex*2+DCLR_FIRSTPATCH, &rect, r, g, b);
7219 	esnprintf(line, 50, x_("%ld"), r);
7220 	DiaSetText(dia, DCLR_REDVAL, line);
7221 	esnprintf(line, 50, x_("%ld"), g);
7222 	DiaSetText(dia, DCLR_GREENVAL, line);
7223 	esnprintf(line, 50, x_("%ld"), b);
7224 	DiaSetText(dia, DCLR_BLUEVAL, line);
7225 }
7226 
7227 /*
7228  * Routine to construct the name of color map entry "ind", given the transparent layer names in "overlayernames".
7229  */
us_colormixentryname(CHAR * overlayernames[],INTBIG ind)7230 CHAR *us_colormixentryname(CHAR *overlayernames[], INTBIG ind)
7231 {
7232 	BOOLEAN gotname;
7233 	REGISTER void *infstr;
7234 
7235 	if (ind == ALLOFF) return(_("Background"));
7236 	if (ind == GRID) return(_("Grid"));
7237 	if (ind == HIGHLIT) return(_("Highlight"));
7238 	if (ind == 0354) return(_("Extra 1"));
7239 	if (ind == 0364) return(_("Extra 2"));
7240 	if (ind == 0374) return(_("Extra 3"));
7241 	if (ind == el_colcelltxt) return(_("Cell Name"));
7242 	if (ind == el_colcell) return(_("Cell Outline"));
7243 	if (ind == el_colwinbor) return(_("Window Border"));
7244 	if (ind == el_colhwinbor) return(_("Current Window Border"));
7245 	if (ind == el_colmenbor) return(_("Component Menu Border"));
7246 	if (ind == el_colhmenbor) return(_("Highlighted Component Menu Border"));
7247 	if (ind == el_colmentxt) return(_("Text in Component Menu"));
7248 	if (ind == el_colmengly) return(_("Glyphs in Component Menu"));
7249 	if (ind == el_colcursor) return(_("Cursor"));
7250 	infstr = initinfstr();
7251 	gotname = FALSE;
7252 	if ((ind&LAYERT1) != 0)
7253 	{
7254 		if (gotname) addstringtoinfstr(infstr, x_(", "));
7255 		addstringtoinfstr(infstr, overlayernames[0]);
7256 		gotname = TRUE;
7257 	}
7258 	if ((ind&LAYERT2) != 0)
7259 	{
7260 		if (gotname) addstringtoinfstr(infstr, x_(", "));
7261 		addstringtoinfstr(infstr, overlayernames[1]);
7262 		gotname = TRUE;
7263 	}
7264 	if ((ind&LAYERT3) != 0)
7265 	{
7266 		if (gotname) addstringtoinfstr(infstr, x_(", "));
7267 		addstringtoinfstr(infstr, overlayernames[2]);
7268 		gotname = TRUE;
7269 	}
7270 	if ((ind&LAYERT4) != 0)
7271 	{
7272 		if (gotname) addstringtoinfstr(infstr, x_(", "));
7273 		addstringtoinfstr(infstr, overlayernames[3]);
7274 		gotname = TRUE;
7275 	}
7276 	if ((ind&LAYERT5) != 0)
7277 	{
7278 		if (gotname) addstringtoinfstr(infstr, x_(", "));
7279 		addstringtoinfstr(infstr, overlayernames[4]);
7280 	}
7281 	return(returninfstr(infstr));
7282 }
7283 
7284 /****************************** COMPONENT MENU DIALOG ******************************/
7285 
7286 /* Component Menu */
7287 static DIALOGITEM us_menuposdialogitems[] =
7288 {
7289  /*  1 */ {0, {128,168,152,232}, BUTTON, N_("OK")},
7290  /*  2 */ {0, {88,168,112,232}, BUTTON, N_("Cancel")},
7291  /*  3 */ {0, {32,200,48,248}, EDITTEXT, x_("")},
7292  /*  4 */ {0, {64,8,80,136}, RADIO, N_("Menu at Top")},
7293  /*  5 */ {0, {88,8,104,136}, RADIO, N_("Menu at Bottom")},
7294  /*  6 */ {0, {112,8,128,136}, RADIO, N_("Menu on Left")},
7295  /*  7 */ {0, {136,8,152,136}, RADIO, N_("Menu on Right")},
7296  /*  8 */ {0, {8,8,24,197}, MESSAGE, N_("Number of Entries Across:")},
7297  /*  9 */ {0, {32,8,48,197}, MESSAGE, N_("Number of Entries Down:")},
7298  /* 10 */ {0, {8,200,24,248}, EDITTEXT, x_("")},
7299  /* 11 */ {0, {160,8,176,100}, RADIO, N_("No Menu")}
7300 };
7301 static DIALOG us_menuposdialog = {{50,75,235,334}, N_("Component Menu Configuration"), 0, 11, us_menuposdialogitems, 0, 0};
7302 
7303 /* special items for the "menu" dialog: */
7304 #define DCMP_DOWN      3		/* Down (edit text) */
7305 #define DCMP_ATTOP     4		/* Menus at top (radio) */
7306 #define DCMP_ATBOT     5		/* Menus at bottom (radio) */
7307 #define DCMP_ATLEFT    6		/* Menus at left (radio) */
7308 #define DCMP_ATRIGHT   7		/* Menus at right (radio) */
7309 #define DCMP_ACROSS_L  8		/* Across label (message) */
7310 #define DCMP_DOWN_L    9		/* Down label (message) */
7311 #define DCMP_ACROSS   10		/* Across (edit text) */
7312 #define DCMP_NOMENU   11		/* No menu (radio) */
7313 
us_menudlog(CHAR * paramstart[])7314 INTBIG us_menudlog(CHAR *paramstart[])
7315 {
7316 	INTBIG itemHit, large, smallf;
7317 	CHAR amt[10];
7318 	REGISTER void *infstr;
7319 	REGISTER void *dia;
7320 
7321 	/* display the menu position dialog box */
7322 	dia = DiaInitDialog(&us_menuposdialog);
7323 	if (dia == 0) return(0);
7324 	if ((us_tool->toolstate&MENUON) == 0)
7325 	{
7326 		DiaSetControl(dia, DCMP_NOMENU, 1);
7327 		DiaNoEditControl(dia, DCMP_DOWN);
7328 		DiaNoEditControl(dia, DCMP_ACROSS);
7329 		DiaDimItem(dia, DCMP_ACROSS_L);
7330 		DiaDimItem(dia, DCMP_DOWN_L);
7331 	} else
7332 	{
7333 		switch (us_menupos)
7334 		{
7335 			case 0: DiaSetControl(dia, DCMP_ATTOP, 1);    break;
7336 			case 1: DiaSetControl(dia, DCMP_ATBOT, 1);    break;
7337 			case 2: DiaSetControl(dia, DCMP_ATLEFT, 1);   break;
7338 			case 3: DiaSetControl(dia, DCMP_ATRIGHT, 1);  break;
7339 		}
7340 		DiaEditControl(dia, DCMP_DOWN);
7341 		DiaEditControl(dia, DCMP_ACROSS);
7342 		DiaUnDimItem(dia, DCMP_ACROSS_L);
7343 		DiaUnDimItem(dia, DCMP_DOWN_L);
7344 	}
7345 	if (us_menux < us_menuy) { large = us_menuy;   smallf = us_menux; } else
7346 		{ large = us_menux;   smallf = us_menuy; }
7347 	if (us_menupos <= 1)
7348 	{
7349 		(void)esnprintf(amt, 10, x_("%ld"), large);
7350 		DiaSetText(dia, DCMP_ACROSS, amt);
7351 		(void)esnprintf(amt, 10, x_("%ld"), smallf);
7352 		DiaSetText(dia, DCMP_DOWN, amt);
7353 	} else
7354 	{
7355 		(void)esnprintf(amt, 10, x_("%ld"), smallf);
7356 		DiaSetText(dia, DCMP_ACROSS, amt);
7357 		(void)esnprintf(amt, 10, x_("%ld"), large);
7358 		DiaSetText(dia, DCMP_DOWN, amt);
7359 	}
7360 
7361 	/* loop until done */
7362 	for(;;)
7363 	{
7364 		itemHit = DiaNextHit(dia);
7365 		if (itemHit == CANCEL) break;
7366 		if (itemHit == OK && DiaValidEntry(dia, DCMP_ACROSS) && DiaValidEntry(dia, DCMP_DOWN)) break;
7367 		if (itemHit == DCMP_ATTOP || itemHit == DCMP_ATBOT ||
7368 			itemHit == DCMP_ATLEFT || itemHit == DCMP_ATRIGHT ||
7369 			itemHit == DCMP_NOMENU)
7370 		{
7371 			DiaSetControl(dia, DCMP_ATTOP, 0);
7372 			DiaSetControl(dia, DCMP_ATBOT, 0);
7373 			DiaSetControl(dia, DCMP_ATLEFT, 0);
7374 			DiaSetControl(dia, DCMP_ATRIGHT, 0);
7375 			DiaSetControl(dia, DCMP_NOMENU, 0);
7376 			DiaSetControl(dia, itemHit, 1);
7377 			if (itemHit == DCMP_NOMENU)
7378 			{
7379 				DiaNoEditControl(dia, DCMP_DOWN);
7380 				DiaNoEditControl(dia, DCMP_ACROSS);
7381 				DiaDimItem(dia, DCMP_ACROSS_L);
7382 				DiaDimItem(dia, DCMP_DOWN_L);
7383 			} else
7384 			{
7385 				DiaEditControl(dia, DCMP_DOWN);
7386 				DiaEditControl(dia, DCMP_ACROSS);
7387 				DiaUnDimItem(dia, DCMP_ACROSS_L);
7388 				DiaUnDimItem(dia, DCMP_DOWN_L);
7389 			}
7390 		}
7391 	}
7392 
7393 	paramstart[0] = x_("");
7394 	if (itemHit != CANCEL)
7395 	{
7396 		infstr = initinfstr();
7397 		if (DiaGetControl(dia, DCMP_NOMENU) != 0) addstringtoinfstr(infstr, x_("off")); else
7398 		{
7399 			if (DiaGetControl(dia, DCMP_ATTOP) != 0) addstringtoinfstr(infstr, x_("top"));
7400 			if (DiaGetControl(dia, DCMP_ATBOT) != 0) addstringtoinfstr(infstr, x_("bottom"));
7401 			if (DiaGetControl(dia, DCMP_ATLEFT) != 0) addstringtoinfstr(infstr, x_("left"));
7402 			if (DiaGetControl(dia, DCMP_ATRIGHT) != 0) addstringtoinfstr(infstr, x_("right"));
7403 			addstringtoinfstr(infstr, x_(" size "));
7404 			addstringtoinfstr(infstr, DiaGetText(dia, DCMP_ACROSS));
7405 			addtoinfstr(infstr, ' ');
7406 			addstringtoinfstr(infstr, DiaGetText(dia, DCMP_DOWN));
7407 		}
7408 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
7409 		allocstring(&us_returneddialogstring, returninfstr(infstr), us_tool->cluster);
7410 		paramstart[0] = us_returneddialogstring;
7411 	}
7412 	DiaDoneDialog(dia);
7413 	return(1);
7414 }
7415 
7416 /****************************** CROSS-LIBRARY COPY DIALOG ******************************/
7417 
7418 /* Copy between libraries */
7419 static DIALOGITEM us_copycelldialogitems[] =
7420 {
7421  /*  1 */ {0, {276,172,300,244}, BUTTON, N_("Done")},
7422  /*  2 */ {0, {8,8,24,168}, POPUP, x_("")},
7423  /*  3 */ {0, {276,40,300,112}, BUTTON, N_("<< Copy")},
7424  /*  4 */ {0, {276,296,300,368}, BUTTON, N_("Copy >>")},
7425  /*  5 */ {0, {32,8,264,172}, SCROLL, x_("")},
7426  /*  6 */ {0, {8,244,24,408}, POPUP, x_("")},
7427  /*  7 */ {0, {324,12,340,192}, BUTTON, N_("Examine contents")},
7428  /*  8 */ {0, {408,8,424,408}, MESSAGE, x_("")},
7429  /*  9 */ {0, {348,12,364,192}, BUTTON, N_("Examine contents quietly")},
7430  /* 10 */ {0, {312,248,328,408}, CHECK, N_("Delete after copy")},
7431  /* 11 */ {0, {384,248,400,408}, CHECK, N_("Copy related views")},
7432  /* 12 */ {0, {336,248,352,408}, CHECK, N_("Copy subcells")},
7433  /* 13 */ {0, {32,244,264,408}, SCROLL, x_("")},
7434  /* 14 */ {0, {32,172,264,244}, SCROLL, x_("")},
7435  /* 15 */ {0, {372,12,388,192}, BUTTON, N_("List differences")},
7436  /* 16 */ {0, {360,248,376,408}, CHECK, N_("Use existing subcells")}
7437 };
7438 static DIALOG us_copycelldialog = {{50,75,483,493}, N_("Cross-Library Copy"), 0, 16, us_copycelldialogitems, 0, 0};
7439 
7440 static void us_loadlibrarycells(LIBRARY *lib, LIBRARY *otherlib, INTBIG examinecontents, BOOLEAN report, void *dia);
7441 static BOOLEAN us_cellexists(NODEPROTO *cell);
7442 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
7443 extern "C"
7444 {
7445 #endif
7446 	static int us_sortxlibentryascending(const void *e1, const void *e2);
7447 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
7448 }
7449 #endif
7450 
7451 /* special items for the "copycell" dialog: */
7452 #define DCPF_FIRSTLIB       2	/* First library (popup) */
7453 #define DCPF_COPYLEFT       3	/* << Copy (button) */
7454 #define DCPF_COPYRIGHT      4	/* Copy >> (button) */
7455 #define DCPF_CELL1LIST      5	/* Cell 1 list (scroll list) */
7456 #define DCPF_OTHERLIB       6	/* Other library (popup) */
7457 #define DCPF_EXCONTENTS     7	/* Examine contents (button) */
7458 #define DCPF_CONTINFO       8	/* contents footnote (stat text) */
7459 #define DCPF_EXCONTENTSQ    9	/* Examine contents quietly (button) */
7460 #define DCPF_DELETEAFTER   10	/* Delete after copy (check) */
7461 #define DCPF_COPYRELATED   11	/* Copy related views (check) */
7462 #define DCPF_COPYSUBCELL   12	/* Copy subcells (check) */
7463 #define DCPF_CELL2LIST     13	/* Cell 2 list (scroll list) */
7464 #define DCPF_CELLDIFFLIST  14	/* Cell difference list (scroll list) */
7465 #define DCPF_LISTDIFFS     15	/* List differences (button) */
7466 #define DCPF_USEEXISTING   16	/* Use existing subcells (check) */
7467 
us_copycelldlog(CHAR * prompt)7468 INTBIG us_copycelldlog(CHAR *prompt)
7469 {
7470 	INTBIG itemHit, libcount, i, len, libindex, otherlibindex, listlen, examinecontents;
7471 	CHAR *lastcellname, *param0, *param1, *newparam[10];
7472 	REGISTER INTBIG ac;
7473 	REGISTER LIBRARY *lib, *otherlib, *olib;
7474 	REGISTER CHAR **liblist, *pt;
7475 	REGISTER WINDOWPART *w;
7476 	static LIBRARY *lastlib = NOLIBRARY, *lastotherlib = NOLIBRARY;
7477 	static INTBIG lastdeleteaftercopy = 0;
7478 	static INTBIG lastcopyrelated = 1;
7479 	static INTBIG lastcopysubcells = 1;
7480 	static INTBIG lastuseexisting = 0;
7481 	REGISTER void *infstr;
7482 	REGISTER void *dia;
7483 
7484 	/* see how many libraries should be in the popups */
7485 	libcount = 0;
7486 	lib = el_curlib;   otherlib = NOLIBRARY;
7487 	for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
7488 	{
7489 		if ((olib->userbits&HIDDENLIBRARY) != 0) continue;
7490 		libcount++;
7491 		if (olib != lib && otherlib == NOLIBRARY) otherlib = olib;
7492 	}
7493 	if (libcount < 2)
7494 	{
7495 		ttyputerr(_("There must be two libraries read in before copying between them"));
7496 		return(0);
7497 	}
7498 
7499 	/* use libraries from previous invocation of this dialog */
7500 	if (lastlib != NOLIBRARY)
7501 	{
7502 		for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
7503 			if (olib == lastlib) lib = lastlib;
7504 	}
7505 	if (lastotherlib != NOLIBRARY)
7506 	{
7507 		for(olib = el_curlib; olib != NOLIBRARY; olib = olib->nextlibrary)
7508 			if (olib == lastotherlib) otherlib = lastotherlib;
7509 	}
7510 
7511 	/* see if the initial library is specified */
7512 	if (*prompt == '!')
7513 	{
7514 		olib = getlibrary(&prompt[1]);
7515 		if (olib != NOLIBRARY && olib != lib)
7516 			otherlib = olib;
7517 	}
7518 
7519 	/* load up list of libraries */
7520 	liblist = us_makelibrarylist(&libcount, el_curlib, &i);
7521 
7522 	/* find requested libraries */
7523 	for(i=0; i<libcount; i++)
7524 	{
7525 		if (namesame(liblist[i], lib->libname) == 0) libindex = i;
7526 		if (namesame(liblist[i], otherlib->libname) == 0) otherlibindex = i;
7527 	}
7528 
7529 	/* display the copycell dialog box */
7530 	dia = DiaInitDialog(&us_copycelldialog);
7531 	if (dia == 0)
7532 	{
7533 		efree((CHAR *)liblist);
7534 		return(0);
7535 	}
7536 	DiaSetPopup(dia, DCPF_FIRSTLIB, libcount, liblist);
7537 	DiaSetPopupEntry(dia, DCPF_FIRSTLIB, libindex);
7538 	DiaSetPopup(dia, DCPF_OTHERLIB, libcount, liblist);
7539 	DiaSetPopupEntry(dia, DCPF_OTHERLIB, otherlibindex);
7540 	DiaUnDimItem(dia, DCPF_EXCONTENTS);
7541 	DiaUnDimItem(dia, DCPF_EXCONTENTSQ);
7542 	DiaSetControl(dia, DCPF_COPYRELATED, lastcopyrelated);
7543 	DiaSetControl(dia, DCPF_COPYSUBCELL, lastcopysubcells);
7544 	DiaSetControl(dia, DCPF_DELETEAFTER, lastdeleteaftercopy);
7545 	DiaSetControl(dia, DCPF_USEEXISTING, lastuseexisting);
7546 	if (lastdeleteaftercopy == 0)
7547 	{
7548 		DiaSetText(dia, DCPF_COPYLEFT, _("<< Copy"));
7549 		DiaSetText(dia, DCPF_COPYRIGHT, _("Copy >>"));
7550 	} else
7551 	{
7552 		DiaSetText(dia, DCPF_COPYLEFT, _("<< Move"));
7553 		DiaSetText(dia, DCPF_COPYRIGHT, _("Move >>"));
7554 	}
7555 	DiaInitTextDialog(dia, DCPF_CELL1LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
7556 		SCREPORT|SCSELMOUSE|SCDOUBLEQUIT|SCSMALLFONT|SCFIXEDWIDTH|SCHORIZBAR);
7557 	DiaInitTextDialog(dia, DCPF_CELL2LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
7558 		SCREPORT|SCSELMOUSE|SCDOUBLEQUIT|SCSMALLFONT|SCFIXEDWIDTH|SCHORIZBAR);
7559 	DiaInitTextDialog(dia, DCPF_CELLDIFFLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
7560 		SCREPORT|SCSELMOUSE|SCSMALLFONT|SCFIXEDWIDTH|SCHORIZBAR);
7561 	DiaSynchVScrolls(dia, DCPF_CELL1LIST, DCPF_CELL2LIST, DCPF_CELLDIFFLIST);
7562 	examinecontents = 0;
7563 	us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7564 
7565 	/* loop until done */
7566 	for(;;)
7567 	{
7568 		itemHit = DiaNextHit(dia);
7569 		if (itemHit == OK) break;
7570 		if (itemHit == DCPF_LISTDIFFS)
7571 		{
7572 			us_loadlibrarycells(lib, otherlib, examinecontents, TRUE, dia);
7573 			continue;
7574 		}
7575 		if (itemHit == DCPF_CELL1LIST)
7576 		{
7577 			i = DiaGetCurLine(dia, DCPF_CELL1LIST);
7578 			DiaSelectLine(dia, DCPF_CELL2LIST, i);
7579 			DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7580 			continue;
7581 		}
7582 		if (itemHit == DCPF_CELL2LIST)
7583 		{
7584 			i = DiaGetCurLine(dia, DCPF_CELL2LIST);
7585 			DiaSelectLine(dia, DCPF_CELL1LIST, i);
7586 			DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7587 			continue;
7588 		}
7589 		if (itemHit == DCPF_CELLDIFFLIST)
7590 		{
7591 			i = DiaGetCurLine(dia, DCPF_CELLDIFFLIST);
7592 			DiaSelectLine(dia, DCPF_CELL1LIST, i);
7593 			DiaSelectLine(dia, DCPF_CELL2LIST, i);
7594 			continue;
7595 		}
7596 		if (itemHit == DCPF_DELETEAFTER)
7597 		{
7598 			lastdeleteaftercopy = 1 - DiaGetControl(dia, itemHit);
7599 			DiaSetControl(dia, itemHit, lastdeleteaftercopy);
7600 			if (lastdeleteaftercopy == 0)
7601 			{
7602 				DiaSetText(dia, DCPF_COPYLEFT, _("<< Copy"));
7603 				DiaSetText(dia, DCPF_COPYRIGHT, _("Copy >>"));
7604 			} else
7605 			{
7606 				DiaSetText(dia, DCPF_COPYLEFT, _("<< Move"));
7607 				DiaSetText(dia, DCPF_COPYRIGHT, _("Move >>"));
7608 			}
7609 			continue;
7610 		}
7611 		if (itemHit == DCPF_USEEXISTING)
7612 		{
7613 			lastuseexisting = 1 - DiaGetControl(dia, itemHit);
7614 			DiaSetControl(dia, itemHit, lastuseexisting);
7615 			continue;
7616 		}
7617 		if (itemHit == DCPF_COPYRELATED)
7618 		{
7619 			lastcopyrelated = 1 - DiaGetControl(dia, itemHit);
7620 			DiaSetControl(dia, itemHit, lastcopyrelated);
7621 			continue;
7622 		}
7623 		if (itemHit == DCPF_COPYSUBCELL)
7624 		{
7625 			lastcopysubcells = 1 - DiaGetControl(dia, itemHit);
7626 			DiaSetControl(dia, itemHit, lastcopysubcells);
7627 			continue;
7628 		}
7629 		if (itemHit == DCPF_COPYLEFT)
7630 		{
7631 			/* copy into the current library ("<< Copy/Move") */
7632 			i = DiaGetCurLine(dia, DCPF_CELL2LIST);
7633 			if (i < 0) continue;
7634 			pt = DiaGetScrollLine(dia, DCPF_CELL2LIST, i);
7635 			if (*pt == 0) continue;
7636 			(void)allocstring(&lastcellname, pt, el_tempcluster);
7637 
7638 			infstr = initinfstr();
7639 			addstringtoinfstr(infstr, otherlib->libname);
7640 			addtoinfstr(infstr, ':');
7641 			addstringtoinfstr(infstr, lastcellname);
7642 			(void)allocstring(&param0, returninfstr(infstr), el_tempcluster);
7643 			ac = 0;
7644 			newparam[ac++] = param0;
7645 
7646 			infstr = initinfstr();
7647 			addstringtoinfstr(infstr, lib->libname);
7648 			addtoinfstr(infstr, ':');
7649 			for(i=0; lastcellname[i] != 0; i++)
7650 			{
7651 				if (lastcellname[i] == '{' || lastcellname[i] == ';') break;
7652 				addtoinfstr(infstr, lastcellname[i]);
7653 			}
7654 			(void)allocstring(&param1, returninfstr(infstr), el_tempcluster);
7655 			newparam[ac++] = param1;
7656 
7657 			/* do the copy */
7658 			if (DiaGetControl(dia, DCPF_DELETEAFTER) != 0) newparam[ac++] = x_("move");
7659 			if (DiaGetControl(dia, DCPF_COPYRELATED) == 0) newparam[ac++] = x_("no-related-views");
7660 			if (DiaGetControl(dia, DCPF_COPYSUBCELL) == 0) newparam[ac++] = x_("no-subcells");
7661 			if (DiaGetControl(dia, DCPF_USEEXISTING) != 0) newparam[ac++] = x_("use-existing-subcells");
7662 			us_copycell(ac, newparam);
7663 			efree(param0);
7664 			efree(param1);
7665 
7666 			/* reload the dialog */
7667 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7668 
7669 			/* reselect the last selected line */
7670 			len = estrlen(lastcellname);
7671 			listlen = DiaGetNumScrollLines(dia, DCPF_CELL1LIST);
7672 			for(i=0; i<listlen; i++)
7673 			{
7674 				pt = DiaGetScrollLine(dia, DCPF_CELL1LIST, i);
7675 				if (estrncmp(lastcellname, pt, len) != 0) continue;
7676 				DiaSelectLine(dia, DCPF_CELL1LIST, i);
7677 				DiaSelectLine(dia, DCPF_CELL2LIST, i);
7678 				DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7679 				break;
7680 			}
7681 			efree(lastcellname);
7682 			continue;
7683 		}
7684 		if (itemHit == DCPF_COPYRIGHT)
7685 		{
7686 			/* copy out of the current library ("Copy/Move >>") */
7687 			i = DiaGetCurLine(dia, DCPF_CELL1LIST);
7688 			if (i < 0) continue;
7689 			pt = DiaGetScrollLine(dia, DCPF_CELL1LIST, i);
7690 			if (*pt == 0) continue;
7691 			(void)allocstring(&lastcellname, pt, el_tempcluster);
7692 
7693 			infstr = initinfstr();
7694 			addstringtoinfstr(infstr, lib->libname);
7695 			addtoinfstr(infstr, ':');
7696 			addstringtoinfstr(infstr, lastcellname);
7697 			(void)allocstring(&param0, returninfstr(infstr), el_tempcluster);
7698 			ac = 0;
7699 			newparam[ac++] = param0;
7700 
7701 			infstr = initinfstr();
7702 			addstringtoinfstr(infstr, otherlib->libname);
7703 			addtoinfstr(infstr, ':');
7704 			for(i=0; lastcellname[i] != 0; i++)
7705 			{
7706 				if (lastcellname[i] == '{' || lastcellname[i] == ';') break;
7707 				addtoinfstr(infstr, lastcellname[i]);
7708 			}
7709 			(void)allocstring(&param1, returninfstr(infstr), el_tempcluster);
7710 			newparam[ac++] = param1;
7711 
7712 			/* do the copy/move */
7713 			if (DiaGetControl(dia, DCPF_DELETEAFTER) != 0) newparam[ac++] = x_("move");
7714 			if (DiaGetControl(dia, DCPF_COPYRELATED) == 0) newparam[ac++] = x_("no-related-views");
7715 			if (DiaGetControl(dia, DCPF_COPYSUBCELL) == 0) newparam[ac++] = x_("no-subcells");
7716 			if (DiaGetControl(dia, DCPF_USEEXISTING) != 0) newparam[ac++] = x_("use-existing-subcells");
7717 			us_copycell(ac, newparam);
7718 			efree(param0);
7719 			efree(param1);
7720 
7721 			/* reload the dialog */
7722 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7723 
7724 			/* reselect the last selected line */
7725 			len = estrlen(lastcellname);
7726 			listlen = DiaGetNumScrollLines(dia, DCPF_CELL2LIST);
7727 			for(i=0; i<listlen; i++)
7728 			{
7729 				pt = DiaGetScrollLine(dia, DCPF_CELL2LIST, i);
7730 				if (estrncmp(lastcellname, pt, len) != 0) continue;
7731 				DiaSelectLine(dia, DCPF_CELL1LIST, i);
7732 				DiaSelectLine(dia, DCPF_CELL2LIST, i);
7733 				DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7734 				break;
7735 			}
7736 			efree(lastcellname);
7737 			continue;
7738 		}
7739 		if (itemHit == DCPF_FIRSTLIB)
7740 		{
7741 			/* selected different left-hand library */
7742 			i = DiaGetPopupEntry(dia, DCPF_FIRSTLIB);
7743 			olib = getlibrary(liblist[i]);
7744 			if (olib == NOLIBRARY) continue;
7745 			lastlib = lib = olib;
7746 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7747 			continue;
7748 		}
7749 		if (itemHit == DCPF_OTHERLIB)
7750 		{
7751 			/* selected different right-hand library */
7752 			i = DiaGetPopupEntry(dia, DCPF_OTHERLIB);
7753 			olib = getlibrary(liblist[i]);
7754 			if (olib == NOLIBRARY) continue;
7755 			lastotherlib = otherlib = olib;
7756 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7757 			continue;
7758 		}
7759 		if (itemHit == DCPF_EXCONTENTS)
7760 		{
7761 			/* examine contents */
7762 			examinecontents = 1;
7763 			DiaDimItem(dia, DCPF_EXCONTENTS);
7764 			DiaDimItem(dia, DCPF_EXCONTENTSQ);
7765 
7766 			/* reload the dialog */
7767 			i = DiaGetCurLine(dia, DCPF_CELL1LIST);
7768 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7769 			DiaSelectLine(dia, DCPF_CELL1LIST, i);
7770 			DiaSelectLine(dia, DCPF_CELL2LIST, i);
7771 			DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7772 			continue;
7773 		}
7774 		if (itemHit == DCPF_EXCONTENTSQ)
7775 		{
7776 			/* examine contents quietly */
7777 			examinecontents = -1;
7778 			DiaDimItem(dia, DCPF_EXCONTENTS);
7779 			DiaDimItem(dia, DCPF_EXCONTENTSQ);
7780 
7781 			/* reload the dialog */
7782 			i = DiaGetCurLine(dia, DCPF_CELL1LIST);
7783 			us_loadlibrarycells(lib, otherlib, examinecontents, FALSE, dia);
7784 			DiaSelectLine(dia, DCPF_CELL1LIST, i);
7785 			DiaSelectLine(dia, DCPF_CELL2LIST, i);
7786 			DiaSelectLine(dia, DCPF_CELLDIFFLIST, i);
7787 			continue;
7788 		}
7789 	}
7790 
7791 	DiaDoneDialog(dia);
7792 	efree((CHAR *)liblist);
7793 
7794 	/* validate all windows */
7795 	for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
7796 	{
7797 		if (w->curnodeproto == NONODEPROTO) continue;
7798 		if (us_cellexists(w->curnodeproto)) continue;
7799 
7800 		/* window no longer valid */
7801 		us_clearwindow(w);
7802 	}
7803 	if (el_curlib->curnodeproto != NONODEPROTO)
7804 	{
7805 		if (!us_cellexists(el_curlib->curnodeproto))
7806 			(void)setval((INTBIG)el_curlib, VLIBRARY, x_("curnodeproto"),
7807 				(INTBIG)NONODEPROTO, VNODEPROTO);
7808 	}
7809 
7810 	/* update status display if necessary */
7811 	if (us_curnodeproto != NONODEPROTO && us_curnodeproto->primindex == 0 &&
7812 		!us_cellexists(us_curnodeproto))
7813 	{
7814 		if ((us_state&NONPERSISTENTCURNODE) != 0) us_setnodeproto(NONODEPROTO); else
7815 			us_setnodeproto(el_curtech->firstnodeproto);
7816 	}
7817 	return(0);
7818 }
7819 
7820 /*
7821  * Routine to return true if cell "cell" exists in a library somewhere.
7822  */
us_cellexists(NODEPROTO * cell)7823 BOOLEAN us_cellexists(NODEPROTO *cell)
7824 {
7825 	REGISTER LIBRARY *lib;
7826 	REGISTER NODEPROTO *np;
7827 
7828 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
7829 	{
7830 		for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
7831 			if (np == cell) return(TRUE);
7832 	}
7833 	return(FALSE);
7834 }
7835 
7836 typedef struct
7837 {
7838 	NODEPROTO *np;
7839 	CHAR      *cellname;
7840 } XLIBENTRY;
7841 
7842 /*
7843  * Helper routine for "esort" that makes cross-lib entries go in ascending order.
7844  */
us_sortxlibentryascending(const void * e1,const void * e2)7845 int us_sortxlibentryascending(const void *e1, const void *e2)
7846 {
7847 	REGISTER XLIBENTRY *xl1, *xl2;
7848 	REGISTER CHAR *c1, *c2;
7849 
7850 	xl1 = (XLIBENTRY *)e1;
7851 	xl2 = (XLIBENTRY *)e2;
7852 	c1 = xl1->cellname;
7853 	c2 = xl2->cellname;
7854 	return(namesame(c1, c2));
7855 }
7856 
7857 /*
7858  * Routine to compare the two libraries "lib" and "otherlib" and list their cells in
7859  * the cross-library copy dialog.  If "examinecontents" is nonzero, compare cell
7860  * contents when their dates don't match (if negative, do so quietly).  If "report" is
7861  * true, just list the differences in the messages window.
7862  */
us_loadlibrarycells(LIBRARY * lib,LIBRARY * otherlib,INTBIG examinecontents,BOOLEAN report,void * dia)7863 void us_loadlibrarycells(LIBRARY *lib, LIBRARY *otherlib, INTBIG examinecontents,
7864 	BOOLEAN report, void *dia)
7865 {
7866 	REGISTER NODEPROTO *np, *curf = NONODEPROTO, *otherf = NONODEPROTO;
7867 	REGISTER INTBIG i, j, curcount, othercount, curpos, otherpos, op;
7868 	REGISTER CHAR *fname, *ofname, *pt;
7869 	REGISTER LIBRARY *oldlib;
7870 	REGISTER XLIBENTRY *curxl, *otherxl;
7871 
7872 	if (!report)
7873 	{
7874 		if (examinecontents != 0) DiaSetText(dia, DCPF_CONTINFO, _("Examining contents..."));
7875 		DiaLoadTextDialog(dia, DCPF_CELL1LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
7876 		DiaLoadTextDialog(dia, DCPF_CELL2LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
7877 		DiaLoadTextDialog(dia, DCPF_CELLDIFFLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
7878 	}
7879 
7880 	/* gather a list of cell names in "lib" */
7881 	curcount = 0;
7882 	for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
7883 		curcount++;
7884 	if (curcount > 0)
7885 	{
7886 		curxl = (XLIBENTRY *)emalloc(curcount * (sizeof (XLIBENTRY)), el_tempcluster);
7887 		if (curxl == 0) return;
7888 		oldlib = el_curlib;   el_curlib = lib;
7889 		for(i=0, np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, i++)
7890 		{
7891 			curxl[i].np = np;
7892 			(void)allocstring(&curxl[i].cellname, describenodeproto(np), el_tempcluster);
7893 		}
7894 		el_curlib = oldlib;
7895 	} else curxl = 0;
7896 
7897 	/* gather a list of cell names in "otherlib" */
7898 	othercount = 0;
7899 	for(np = otherlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
7900 		othercount++;
7901 	if (othercount > 0)
7902 	{
7903 		otherxl = (XLIBENTRY *)emalloc(othercount * (sizeof (XLIBENTRY)), el_tempcluster);
7904 		if (otherxl == 0) return;
7905 		oldlib = el_curlib;   el_curlib = otherlib;
7906 		for(i=0, np = otherlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, i++)
7907 		{
7908 			otherxl[i].np = np;
7909 			(void)allocstring(&otherxl[i].cellname, describenodeproto(np), el_tempcluster);
7910 		}
7911 		el_curlib = oldlib;
7912 	} else otherxl = 0;
7913 
7914 	/* sort the list of names in the current library */
7915 	esort(curxl, curcount, sizeof (XLIBENTRY), us_sortxlibentryascending);
7916 	esort(otherxl, othercount, sizeof (XLIBENTRY), us_sortxlibentryascending);
7917 
7918 	/* put out the parallel list of cells in the two libraries */
7919 	curpos = otherpos = 0;
7920 	for(;;)
7921 	{
7922 		if (curpos >= curcount && otherpos >= othercount) break;
7923 		if (curpos >= curcount) op = 2; else
7924 			if (otherpos >= othercount) op = 1; else
7925 		{
7926 			curf = curxl[curpos].np;
7927 			otherf = otherxl[otherpos].np;
7928 			j = namesame(curxl[curpos].cellname, otherxl[otherpos].cellname);
7929 			if (j < 0) op = 1; else
7930 				if (j > 0) op = 2; else
7931 					op = 3;
7932 		}
7933 
7934 		if (op != 1 && op != 3) fname = x_(""); else
7935 			fname = curxl[curpos++].cellname;
7936 		if (!report) DiaStuffLine(dia, DCPF_CELL1LIST, fname);
7937 
7938 		if (op != 2 && op != 3) ofname = x_(""); else
7939 			ofname = otherxl[otherpos++].cellname;
7940 		if (!report) DiaStuffLine(dia, DCPF_CELL2LIST, ofname);
7941 
7942 		if (op == 3)
7943 		{
7944 			if (curf->revisiondate < otherf->revisiondate)
7945 			{
7946 				if (examinecontents != 0)
7947 				{
7948 					if (us_samecontents(curf, otherf, examinecontents))
7949 					{
7950 						pt = _("<-OLD");
7951 						if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s (but contents are the same)"),
7952 							lib->libname, fname, otherlib->libname, ofname);
7953 					} else
7954 					{
7955 						pt = _("<-OLD*");
7956 						if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s (and contents are different)"),
7957 							lib->libname, fname, otherlib->libname, ofname);
7958 					}
7959 				} else
7960 				{
7961 					pt = _("<-OLD");
7962 					if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s"),
7963 						lib->libname, fname, otherlib->libname, ofname);
7964 				}
7965 			} else if (curf->revisiondate > otherf->revisiondate)
7966 			{
7967 				if (examinecontents != 0)
7968 				{
7969 					if (us_samecontents(curf, otherf, examinecontents))
7970 					{
7971 						pt = _("  OLD->");
7972 						if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s (but contents are the same)"),
7973 							otherlib->libname, ofname, lib->libname, fname);
7974 					} else
7975 					{
7976 						pt = _(" *OLD->");
7977 						if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s (and contents are different)"),
7978 							otherlib->libname, ofname, lib->libname, fname);
7979 					}
7980 				} else
7981 				{
7982 					pt = _("  OLD->");
7983 					if (report) ttyputmsg(x_("%s:%s OLDER THAN %s:%s"),
7984 						otherlib->libname, ofname, lib->libname, fname);
7985 				}
7986 			} else
7987 			{
7988 				pt = _("-EQUAL-");
7989 			}
7990 		} else
7991 		{
7992 			pt = x_("");
7993 		}
7994 		if (!report) DiaStuffLine(dia, DCPF_CELLDIFFLIST, pt);
7995 	}
7996 	if (!report)
7997 	{
7998 		DiaSelectLine(dia, DCPF_CELL1LIST, 0);
7999 		DiaSelectLine(dia, DCPF_CELL2LIST, 0);
8000 		DiaSelectLine(dia, DCPF_CELLDIFFLIST, 0);
8001 	}
8002 
8003 	/* clean up */
8004 	for(i=0; i<curcount; i++) efree(curxl[i].cellname);
8005 	if (curcount > 0) 	efree((CHAR *)curxl);
8006 	for(i=0; i<othercount; i++) efree(otherxl[i].cellname);
8007 	if (othercount > 0) efree((CHAR *)otherxl);
8008 	if (!report)
8009 	{
8010 		if (examinecontents != 0) DiaSetText(dia, DCPF_CONTINFO, _("* contents differ"));
8011 	}
8012 }
8013 
8014 /****************************** CELL EDIT/CREATE DIALOGS ******************************/
8015 
8016 /* Edit cell */
8017 static DIALOGITEM us_editcelldialogitems[] =
8018 {
8019  /*  1 */ {0, {284,208,308,272}, BUTTON, N_("OK")},
8020  /*  2 */ {0, {284,16,308,80}, BUTTON, N_("Cancel")},
8021  /*  3 */ {0, {32,8,208,280}, SCROLL, x_("")},
8022  /*  4 */ {0, {212,8,228,153}, CHECK, N_("Show old versions")},
8023  /*  5 */ {0, {260,8,276,231}, CHECK, N_("Make new window for cell")},
8024  /*  6 */ {0, {284,104,308,187}, BUTTON, N_("New Cell")},
8025  /*  7 */ {0, {8,8,24,67}, MESSAGE, N_("Library:")},
8026  /*  8 */ {0, {8,72,24,280}, POPUP, x_("")},
8027  /*  9 */ {0, {236,8,252,231}, CHECK, N_("Show cells from Cell-Library")},
8028  /* 10 */ {0, {331,8,347,213}, EDITTEXT, x_("")},
8029  /* 11 */ {0, {328,216,352,280}, BUTTON, N_("Rename")},
8030  /* 12 */ {0, {356,144,380,208}, BUTTON, N_("Delete")},
8031  /* 13 */ {0, {316,8,317,280}, DIVIDELINE, N_("item")},
8032  /* 14 */ {0, {360,8,376,137}, CHECK, N_("Confirm deletion")}
8033 };
8034 static DIALOG us_editcelldialog = {{50,75,439,365}, N_("Edit Cell"), 0, 14, us_editcelldialogitems, 0, 0};
8035 
8036 /* special items for the "edit cell" command: */
8037 #define DEDF_CELLLIST       3		/* Cell list (stat text) */
8038 #define DEDF_SHOWOLDVERS    4		/* Show old versions (check) */
8039 #define DEDF_NEWWINDOW      5		/* Make new window for cell (check) */
8040 #define DEDF_NEWCELL        6		/* New cell (button) */
8041 #define DEDF_LIBRARYNAME    8		/* Library name (popup) */
8042 #define DEDF_INCLCELLLIB    9		/* Show from cell-library (check) */
8043 #define DEDF_NEWNAME       10		/* New cell name (edit text) */
8044 #define DEDF_RENAME        11		/* Rename cell (button) */
8045 #define DEDF_DELETE        12		/* Delete cell (button) */
8046 #define DEDF_CONFIRMDELETE 14		/* Confirm cell deletion (check) */
8047 
8048 /* New cell */
8049 static DIALOGITEM us_newcelldialogitems[] =
8050 {
8051  /*  1 */ {0, {56,304,80,368}, BUTTON, N_("OK")},
8052  /*  2 */ {0, {56,12,80,76}, BUTTON, N_("Cancel")},
8053  /*  3 */ {0, {8,160,24,367}, EDITTEXT, x_("")},
8054  /*  4 */ {0, {8,8,24,157}, MESSAGE, N_("Name of new cell:")},
8055  /*  5 */ {0, {32,160,48,367}, POPUP, x_("")},
8056  /*  6 */ {0, {32,56,48,149}, MESSAGE, N_("Cell view:")},
8057  /*  7 */ {0, {60,84,78,297}, CHECK, N_("Make new window for cell")}
8058 };
8059 static DIALOG us_newcelldialog = {{350,75,445,455}, N_("New Cell Creation"), 0, 7, us_newcelldialogitems, 0, 0};
8060 
8061 /* special items for the "new cell" command: */
8062 #define DNWF_CELLNAME      3		/* Cell name (edit text) */
8063 #define DNWF_VIEWLIST      5		/* View list (popup) */
8064 #define DNWF_NEWWINDOW     7		/* Make new window for cell (check) */
8065 
us_editcelldlog(CHAR * prompt)8066 INTBIG us_editcelldlog(CHAR *prompt)
8067 {
8068 	INTBIG itemHit, libcount, i;
8069 	REGISTER INTBIG viewcount, libindex, defaultindex, listlen;
8070 	REGISTER NODEPROTO *np, *curcell;
8071 	static BOOLEAN confirmdelete = TRUE;
8072 	CHAR **viewlist, **librarylist, *pt, *ptr, *newpar[5];
8073 	REGISTER VIEW *v;
8074 	static INTBIG makenewwindow = -1;
8075 	static VIEW *lastview = NOVIEW;
8076 	VIEW *thisview;
8077 	REGISTER void *infstr, *dia, *subdia;
8078 
8079 	/* make a list of view names */
8080 	viewcount = us_makeviewlist(&viewlist);
8081 	if (viewcount == 0) return(0);
8082 
8083 	/* see what the current view is (if any) */
8084 	thisview = lastview;
8085 	if (el_curwindowpart != NOWINDOWPART)
8086 	{
8087 		if (el_curwindowpart->curnodeproto != NONODEPROTO)
8088 			thisview = el_curwindowpart->curnodeproto->cellview;
8089 	}
8090 	defaultindex = 0;
8091 	if (thisview != NOVIEW)
8092 	{
8093 		for(i=0; i<viewcount; i++)
8094 			if (estrcmp(viewlist[i], thisview->viewname) == 0) defaultindex = i;
8095 	}
8096 
8097 	/* the general case: display the dialog box */
8098 	us_curlib = el_curlib;
8099 	for(pt = prompt; *pt != 0; pt++) if (*pt == '/') break;
8100 	if (*pt == '/')
8101 	{
8102 		*pt++ = 0;
8103 		us_curlib = getlibrary(prompt);
8104 		if (us_curlib == NOLIBRARY) us_curlib = el_curlib;
8105 		prompt = pt;
8106 	}
8107 
8108 	us_editcelldialog.movable = prompt;
8109 	if (us_curlib->firstnodeproto == NONODEPROTO)
8110 	{
8111 		us_editcelldialogitems[OK-1].type = BUTTON;
8112 		us_editcelldialogitems[DEDF_NEWCELL-1].type = DEFBUTTON;
8113 	} else
8114 	{
8115 		us_editcelldialogitems[OK-1].type = DEFBUTTON;
8116 		us_editcelldialogitems[DEDF_NEWCELL-1].type = BUTTON;
8117 	}
8118 	dia = DiaInitDialog(&us_editcelldialog);
8119 	if (dia == 0) return(0);
8120 
8121 	if (confirmdelete) DiaSetControl(dia, DEDF_CONFIRMDELETE, 1);
8122 
8123 	/* make a list of library names */
8124 	librarylist = us_makelibrarylist(&libcount, us_curlib, &i);
8125 	libindex = 0;
8126 	for(i=0; i<libcount; i++)
8127 		if (namesame(librarylist[i], us_curlib->libname) == 0) libindex = i;
8128 	DiaSetPopup(dia, DEDF_LIBRARYNAME, libcount, librarylist);
8129 	DiaSetPopupEntry(dia, DEDF_LIBRARYNAME, libindex);
8130 
8131 	/* show the cells */
8132 	us_showoldversions = us_defshowoldversions;
8133 	us_showcellibrarycells = us_defshowcellibrarycells;
8134 	us_showonlyrelevantcells = 0;
8135 	DiaInitTextDialog(dia, DEDF_CELLLIST, us_oldcelltopofcells, us_oldcellnextcells,
8136 		DiaNullDlogDone, 0, SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT|SCREPORT);
8137 
8138 	/* find the current node and make it the default */
8139 	(void)us_setscrolltocurrentcell(DEDF_CELLLIST, FALSE, TRUE, TRUE, FALSE, dia);
8140 	np = us_getselectedcell(dia);
8141 	if (np != NONODEPROTO)
8142 		DiaSetText(dia, DEDF_NEWNAME, np->protoname);
8143 
8144 	/* see if there are any old versions */
8145 	for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8146 		if (np->newestversion != np) break;
8147 	if (np == NONODEPROTO) DiaDimItem(dia, DEDF_SHOWOLDVERS); else
8148 	{
8149 		DiaUnDimItem(dia, DEDF_SHOWOLDVERS);
8150 		DiaSetControl(dia, DEDF_SHOWOLDVERS, us_showoldversions);
8151 	}
8152 
8153 	/* see if there are any cell-library cells */
8154 	for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8155 		if ((np->userbits&INCELLLIBRARY) != 0) break;
8156 	if (np == NONODEPROTO) DiaDimItem(dia, DEDF_INCLCELLLIB); else
8157 	{
8158 		DiaUnDimItem(dia, DEDF_INCLCELLLIB);
8159 		DiaSetControl(dia, DEDF_INCLCELLLIB, us_showcellibrarycells);
8160 	}
8161 
8162 	/* if the current window has a cell in it and multiple windows are supported, offer new one */
8163 	curcell = getcurcell();
8164 	if (makenewwindow < 0)
8165 	{
8166 		makenewwindow = 0;
8167 		if (curcell != NONODEPROTO && graphicshas(CANUSEFRAMES)) makenewwindow = 1;
8168 	}
8169 	DiaSetControl(dia, DEDF_NEWWINDOW, makenewwindow);
8170 	for(;;)
8171 	{
8172 		itemHit = DiaNextHit(dia);
8173 		if (itemHit == CANCEL) break;
8174 		if (itemHit == OK)
8175 		{
8176 			np = us_getselectedcell(dia);
8177 			if (np == NONODEPROTO) continue;
8178 			allocstring(&us_returneddialogstring, describenodeproto(np), us_tool->cluster);
8179 			newpar[0] = us_returneddialogstring;
8180 			break;
8181 		}
8182 		if (itemHit == DEDF_CONFIRMDELETE)
8183 		{
8184 			confirmdelete = !confirmdelete;
8185 			if (confirmdelete) DiaSetControl(dia, DEDF_CONFIRMDELETE, 1); else
8186 				DiaSetControl(dia, DEDF_CONFIRMDELETE, 0);
8187 			continue;
8188 		}
8189 		if (itemHit == DEDF_NEWWINDOW)
8190 		{
8191 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
8192 			continue;
8193 		}
8194 		if (itemHit == DEDF_RENAME)
8195 		{
8196 			np = us_getselectedcell(dia);
8197 			if (np == NONODEPROTO) continue;
8198 
8199 			pt = DiaGetText(dia, DEDF_NEWNAME);
8200 			if (estrcmp(np->protoname, pt) == 0) continue;
8201 
8202 			i = DiaGetCurLine(dia, DEDF_CELLLIST);
8203 			allocstring(&newpar[0], describenodeproto(np), el_tempcluster);
8204 			allocstring(&newpar[1], pt, el_tempcluster);
8205 			newpar[2] = x_("p");
8206 			us_rename(3, newpar);
8207 			efree((CHAR *)newpar[0]);
8208 			efree((CHAR *)newpar[1]);
8209 			DiaSetScrollLine(dia, DEDF_CELLLIST, i, nldescribenodeproto(np));
8210 			continue;
8211 		}
8212 		if (itemHit == DEDF_DELETE)
8213 		{
8214 			np = us_getselectedcell(dia);
8215 			if (np == NONODEPROTO) continue;
8216 			if (confirmdelete)
8217 			{
8218 				infstr = initinfstr();
8219 				formatinfstr(infstr, _("Are you sure you want to delete cell %s?"),
8220 					describenodeproto(np));
8221 				if (us_yesnodlog(returninfstr(infstr), newpar) == 0) continue;
8222 				if (namesame(newpar[0], x_("yes")) != 0) continue;
8223 			}
8224 			allocstring(&us_returneddialogstring, describenodeproto(np), us_tool->cluster);
8225 			newpar[0] = us_returneddialogstring;
8226 			us_killcell(1, newpar);
8227 			efree((CHAR *)us_returneddialogstring);
8228 			i = DiaGetCurLine(dia, DEDF_CELLLIST);
8229 			DiaLoadTextDialog(dia, DEDF_CELLLIST, us_oldcelltopofcells, us_oldcellnextcells,
8230 				DiaNullDlogDone, 0);
8231 			if (*DiaGetScrollLine(dia, DEDF_CELLLIST, i) == 0) i--;
8232 			DiaSelectLine(dia, DEDF_CELLLIST, i);
8233 			continue;
8234 		}
8235 		if (itemHit == DEDF_CELLLIST)
8236 		{
8237 			np = us_getselectedcell(dia);
8238 			if (np != NONODEPROTO)
8239 				DiaSetText(dia, DEDF_NEWNAME, np->protoname);
8240 			continue;
8241 		}
8242 		if (itemHit == DEDF_LIBRARYNAME)
8243 		{
8244 			i = DiaGetPopupEntry(dia, DEDF_LIBRARYNAME);
8245 			us_curlib = getlibrary(librarylist[i]);
8246 			DiaLoadTextDialog(dia, DEDF_CELLLIST, us_oldcelltopofcells,
8247 				us_oldcellnextcells, DiaNullDlogDone, 0);
8248 			np = us_getselectedcell(dia);
8249 			if (np == NONODEPROTO) DiaSetText(dia, DEDF_NEWNAME, x_("")); else
8250 				DiaSetText(dia, DEDF_NEWNAME, np->protoname);
8251 
8252 			/* see if there are any old versions */
8253 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8254 				if (np->newestversion != np) break;
8255 			if (np == NONODEPROTO) DiaDimItem(dia, DEDF_SHOWOLDVERS); else
8256 			{
8257 				DiaUnDimItem(dia, DEDF_SHOWOLDVERS);
8258 				DiaSetControl(dia, DEDF_SHOWOLDVERS, us_showoldversions);
8259 			}
8260 
8261 			/* see if there are any cell-library cells */
8262 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8263 				if ((np->userbits&INCELLLIBRARY) != 0) break;
8264 			if (np == NONODEPROTO) DiaDimItem(dia, DEDF_INCLCELLLIB); else
8265 			{
8266 				DiaUnDimItem(dia, DEDF_INCLCELLLIB);
8267 				DiaSetControl(dia, DEDF_INCLCELLLIB, us_showcellibrarycells);
8268 			}
8269 			continue;
8270 		}
8271 		if (itemHit == DEDF_SHOWOLDVERS)
8272 		{
8273 			us_defshowoldversions = us_showoldversions = 1 - DiaGetControl(dia, DEDF_SHOWOLDVERS);
8274 			DiaSetControl(dia, DEDF_SHOWOLDVERS, us_showoldversions);
8275 			i = DiaGetCurLine(dia, DEDF_CELLLIST);
8276 			if (i >= 0) pt = DiaGetScrollLine(dia, DEDF_CELLLIST, i); else pt = x_("");
8277 			DiaLoadTextDialog(dia, DEDF_CELLLIST, us_oldcelltopofcells,
8278 				us_oldcellnextcells, DiaNullDlogDone, 0);
8279 			if (*pt != 0)
8280 			{
8281 				listlen = DiaGetNumScrollLines(dia, DEDF_CELLLIST);
8282 				for(i=0; i<listlen; i++)
8283 				{
8284 					ptr = DiaGetScrollLine(dia, DEDF_CELLLIST, i);
8285 					if (estrcmp(ptr, pt) != 0) continue;
8286 					DiaSelectLine(dia, DEDF_CELLLIST, i);
8287 					break;
8288 				}
8289 			}
8290 			continue;
8291 		}
8292 		if (itemHit == DEDF_INCLCELLLIB)
8293 		{
8294 			us_defshowcellibrarycells = us_showcellibrarycells = 1 - DiaGetControl(dia, DEDF_INCLCELLLIB);
8295 			DiaSetControl(dia, DEDF_INCLCELLLIB, us_showcellibrarycells);
8296 			i = DiaGetCurLine(dia, DEDF_CELLLIST);
8297 			if (i >= 0) pt = DiaGetScrollLine(dia, DEDF_CELLLIST, i); else pt = x_("");
8298 			DiaLoadTextDialog(dia, DEDF_CELLLIST, us_oldcelltopofcells,
8299 				us_oldcellnextcells, DiaNullDlogDone, 0);
8300 			if (*pt != 0)
8301 			{
8302 				listlen = DiaGetNumScrollLines(dia, DEDF_CELLLIST);
8303 				for(i=0; i<listlen; i++)
8304 				{
8305 					ptr = DiaGetScrollLine(dia, DEDF_CELLLIST, i);
8306 					if (estrcmp(ptr, pt) != 0) continue;
8307 					DiaSelectLine(dia, DEDF_CELLLIST, i);
8308 					break;
8309 				}
8310 			}
8311 			continue;
8312 		}
8313 		if (itemHit == DEDF_NEWCELL)
8314 		{
8315 			/* display the new cell dialog box */
8316 			makenewwindow = DiaGetControl(dia, DEDF_NEWWINDOW);
8317 			subdia = DiaInitDialog(&us_newcelldialog);
8318 			if (subdia == 0) continue;
8319 			DiaSetPopup(subdia, DNWF_VIEWLIST, viewcount, viewlist);
8320 			DiaSetControl(subdia, DNWF_NEWWINDOW, makenewwindow);
8321 			DiaSetPopupEntry(subdia, DNWF_VIEWLIST, defaultindex);
8322 
8323 			/* loop until done */
8324 			for(;;)
8325 			{
8326 				itemHit = DiaNextHit(subdia);
8327 				if (itemHit == CANCEL) break;
8328 				if (itemHit == DNWF_NEWWINDOW)
8329 				{
8330 					DiaSetControl(subdia, itemHit, 1 - DiaGetControl(subdia, itemHit));
8331 					continue;
8332 				}
8333 				if (itemHit == OK && DiaValidEntry(subdia, DNWF_CELLNAME)) break;
8334 			}
8335 
8336 			newpar[0] = x_("");
8337 			if (itemHit != CANCEL)
8338 			{
8339 				i = DiaGetPopupEntry(subdia, DNWF_VIEWLIST);
8340 				infstr = initinfstr();
8341 				addstringtoinfstr(infstr, us_curlib->libname);
8342 				addtoinfstr(infstr, ':');
8343 				addstringtoinfstr(infstr, DiaGetText(subdia, DNWF_CELLNAME));
8344 				for(v = el_views; v != NOVIEW; v = v->nextview)
8345 					if (estrcmp(viewlist[i], v->viewname) == 0)
8346 				{
8347 					if (*v->sviewname == 0) break;
8348 					addtoinfstr(infstr, '{');
8349 					addstringtoinfstr(infstr, v->sviewname);
8350 					addtoinfstr(infstr, '}');
8351 					lastview = v;
8352 					break;
8353 				}
8354 				if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
8355 				allocstring(&us_returneddialogstring, returninfstr(infstr), us_tool->cluster);
8356 				newpar[0] = us_returneddialogstring;
8357 			}
8358 			makenewwindow = DiaGetControl(subdia, DNWF_NEWWINDOW);
8359 			DiaDoneDialog(subdia);
8360 			if (itemHit == CANCEL) continue;
8361 			DiaSetControl(dia, DEDF_NEWWINDOW, makenewwindow);
8362 			break;
8363 		}
8364 	}
8365 	makenewwindow = DiaGetControl(dia, DEDF_NEWWINDOW);
8366 	DiaDoneDialog(dia);
8367 	efree((CHAR *)librarylist);
8368 	efree((CHAR *)viewlist);
8369 	if (itemHit != CANCEL)
8370 	{
8371 		if (makenewwindow != 0 && curcell != NONODEPROTO)
8372 		{
8373 			newpar[1] = x_("new-window");
8374 			us_editcell(2, newpar);
8375 		} else
8376 		{
8377 			us_editcell(1, newpar);
8378 		}
8379 	}
8380 	return(0);
8381 }
8382 
8383 /*
8384  * Routine to get the cell currently selected in the "edit cells" dialog.
8385  */
us_getselectedcell(void * dia)8386 NODEPROTO *us_getselectedcell(void *dia)
8387 {
8388 	REGISTER INTBIG i;
8389 	REGISTER void *infstr;
8390 	REGISTER CHAR *pt;
8391 	REGISTER NODEPROTO *np;
8392 
8393 	i = DiaGetCurLine(dia, DEDF_CELLLIST);
8394 	if (i < 0) return(NONODEPROTO);
8395 	pt = DiaGetScrollLine(dia, DEDF_CELLLIST, i);
8396 	if (*pt == 0) return(NONODEPROTO);
8397 	infstr = initinfstr();
8398 	addstringtoinfstr(infstr, us_curlib->libname);
8399 	addtoinfstr(infstr, ':');
8400 	addstringtoinfstr(infstr, pt);
8401 	np = getnodeproto(returninfstr(infstr));
8402 	return(np);
8403 }
8404 
8405 /****************************** CELL LISTS ******************************/
8406 
8407 /* Cell Lists */
8408 static DIALOGITEM us_faclisdialogitems[] =
8409 {
8410  /*  1 */ {0, {464,152,488,232}, BUTTON, N_("OK")},
8411  /*  2 */ {0, {464,32,488,112}, BUTTON, N_("Cancel")},
8412  /*  3 */ {0, {160,22,176,198}, CHECK, N_("Show only this view:")},
8413  /*  4 */ {0, {180,38,196,214}, POPUP, x_("")},
8414  /*  5 */ {0, {200,22,216,198}, CHECK, N_("Also include icon views")},
8415  /*  6 */ {0, {252,22,268,198}, CHECK, N_("Exclude older versions")},
8416  /*  7 */ {0, {140,10,156,186}, MESSAGE, N_("View filter:")},
8417  /*  8 */ {0, {232,10,248,186}, MESSAGE, N_("Version filter:")},
8418  /*  9 */ {0, {272,22,288,198}, CHECK, N_("Exclude newest versions")},
8419  /* 10 */ {0, {8,8,24,184}, MESSAGE, N_("Which cells:")},
8420  /* 11 */ {0, {88,20,104,248}, RADIO, N_("Only those under current cell")},
8421  /* 12 */ {0, {304,8,320,184}, MESSAGE, N_("Display ordering:")},
8422  /* 13 */ {0, {324,20,340,248}, RADIO, N_("Order by name")},
8423  /* 14 */ {0, {344,20,360,248}, RADIO, N_("Order by modification date")},
8424  /* 15 */ {0, {364,20,380,248}, RADIO, N_("Order by skeletal structure")},
8425  /* 16 */ {0, {396,8,412,184}, MESSAGE, N_("Destination:")},
8426  /* 17 */ {0, {416,16,432,244}, RADIO, N_("Display in messages window")},
8427  /* 18 */ {0, {436,16,452,244}, RADIO, N_("Save to disk")},
8428  /* 19 */ {0, {48,20,64,248}, RADIO, N_("Only those used elsewhere")},
8429  /* 20 */ {0, {108,20,124,248}, RADIO, N_("Only placeholder cells")},
8430  /* 21 */ {0, {28,20,44,248}, RADIO, N_("All cells")},
8431  /* 22 */ {0, {132,8,133,248}, DIVIDELINE, x_("")},
8432  /* 23 */ {0, {224,8,225,248}, DIVIDELINE, x_("")},
8433  /* 24 */ {0, {296,8,297,248}, DIVIDELINE, x_("")},
8434  /* 25 */ {0, {388,8,389,248}, DIVIDELINE, x_("")},
8435  /* 26 */ {0, {68,20,84,248}, RADIO, N_("Only those not used elsewhere")}
8436 };
8437 static DIALOG us_faclisdialog = {{75,75,572,333}, N_("Cell Lists"), 0, 26, us_faclisdialogitems, 0, 0};
8438 
8439 /* special items for the "Cell lists" dialog: */
8440 #define DFCL_ONEVIEW        3		/* Show just one view (check) */
8441 #define DFCL_THEVIEW        4		/* The view to show (popup) */
8442 #define DFCL_ICONSVIEWS     5		/* Show icon views too (check) */
8443 #define DFCL_NOOLDVERS      6		/* Exclude older versions (check) */
8444 #define DFCL_NONEWVERS      9		/* Exclude newest versions (check) */
8445 #define DFCL_UNDERTHIS     11		/* Only those under current cell (radio) */
8446 #define DFCL_BYNAME        13		/* Order by name (radio) */
8447 #define DFCL_BYDATE        14		/* Order by modification date (radio) */
8448 #define DFCL_BYSKELETON    15		/* Order by skeletal structure (radio) */
8449 #define DFCL_TOMESSAGES    17		/* Display in messages window (radio) */
8450 #define DFCL_TODISK        18		/* Display in disk file (radio) */
8451 #define DFCL_INUSE         19		/* Only those used elsewhere (radio) */
8452 #define DFCL_PLACEHOLDERS  20		/* Only placeholder cells (radio) */
8453 #define DFCL_ALLCELLS      21		/* All cells (radio) */
8454 #define DFCL_NOTINUSE      26		/* Only those not used elsewhere (radio) */
8455 
8456 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
8457 extern "C"
8458 {
8459 #endif
8460 	static int us_sortbycelldate(const void *e1, const void *e2);
8461 	static int us_sortbycellname(const void *e1, const void *e2);
8462 	static int us_sortbyskeletonstructure(const void *e1, const void *e2);
8463 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
8464 }
8465 #endif
8466 
us_celllist(void)8467 INTBIG us_celllist(void)
8468 {
8469 	REGISTER INTBIG itemHit, viewcount, i, total, maxlen;
8470 	CHAR **viewlist, *truename;
8471 	REGISTER LIBRARY *lib, *savelib;
8472 	REGISTER VARIABLE *var;
8473 	REGISTER NODEINST *ni;
8474 	REGISTER VIEW *v;
8475 	REGISTER void *infstr;
8476 	FILE *dumpfile;
8477 	REGISTER NODEPROTO *np, *inp, **nplist, *curf;
8478 	static INTBIG sortorder = DFCL_BYNAME;
8479 	static INTBIG where = DFCL_TOMESSAGES;
8480 	static INTBIG which = DFCL_ALLCELLS;
8481 	static INTBIG oldvers = 0, newvers = 0, alsoiconview = 0, oneview = 0;
8482 	static VIEW *lastview = NOVIEW;
8483 	REGISTER void *dia;
8484 
8485 	viewcount = us_makeviewlist(&viewlist);
8486 	if (viewcount == 0) return(0);
8487 
8488 	/* display the dialog box */
8489 	dia = DiaInitDialog(&us_faclisdialog);
8490 	if (dia == 0) return(0);
8491 	DiaSetPopup(dia, DFCL_THEVIEW, viewcount, viewlist);
8492 
8493 	/* restore defaults */
8494 	if (lastview != NOVIEW)
8495 	{
8496 		for(i=0; i<viewcount; i++)
8497 			if (getview(viewlist[i]) == lastview) break;
8498 		if (i < viewcount) DiaSetPopupEntry(dia, DFCL_THEVIEW, i);
8499 	}
8500 	curf = getcurcell();
8501 	if (curf != NONODEPROTO) DiaUnDimItem(dia, DFCL_UNDERTHIS); else
8502 	{
8503 		if (which == DFCL_UNDERTHIS) which = DFCL_ALLCELLS;
8504 		DiaDimItem(dia, DFCL_UNDERTHIS);
8505 	}
8506 	DiaSetControl(dia, sortorder, 1);
8507 	DiaSetControl(dia, where, 1);
8508 	DiaSetControl(dia, which, 1);
8509 	DiaSetControl(dia, DFCL_NOOLDVERS, oldvers);
8510 	DiaSetControl(dia, DFCL_NONEWVERS, newvers);
8511 	DiaSetControl(dia, DFCL_ICONSVIEWS, alsoiconview);
8512 	DiaSetControl(dia, DFCL_ONEVIEW, oneview);
8513 	if (DiaGetControl(dia, DFCL_ONEVIEW) == 0)
8514 	{
8515 		DiaDimItem(dia, DFCL_ICONSVIEWS);
8516 		DiaDimItem(dia, DFCL_THEVIEW);
8517 	} else
8518 	{
8519 		DiaUnDimItem(dia, DFCL_ICONSVIEWS);
8520 		DiaUnDimItem(dia, DFCL_THEVIEW);
8521 	}
8522 
8523 	for(;;)
8524 	{
8525 		itemHit = DiaNextHit(dia);
8526 		if (itemHit == OK || itemHit == CANCEL) break;
8527 		if (itemHit == DFCL_THEVIEW)
8528 		{
8529 			i = DiaGetPopupEntry(dia, DFCL_THEVIEW);
8530 			lastview = getview(viewlist[i]);
8531 			continue;
8532 		}
8533 		if (itemHit == DFCL_ONEVIEW || itemHit == DFCL_ICONSVIEWS ||
8534 			itemHit == DFCL_NOOLDVERS || itemHit == DFCL_NONEWVERS)
8535 		{
8536 			i = 1-DiaGetControl(dia, itemHit);
8537 			DiaSetControl(dia, itemHit, i);
8538 			switch (itemHit)
8539 			{
8540 				case DFCL_NOOLDVERS:  oldvers = i;      break;
8541 				case DFCL_NONEWVERS:  newvers = i;      break;
8542 				case DFCL_ICONSVIEWS: alsoiconview = i; break;
8543 				case DFCL_ONEVIEW:
8544 					oneview = i;
8545 					if (i == 0)
8546 					{
8547 						DiaDimItem(dia, DFCL_ICONSVIEWS);
8548 						DiaDimItem(dia, DFCL_THEVIEW);
8549 					} else
8550 					{
8551 						DiaUnDimItem(dia, DFCL_ICONSVIEWS);
8552 						DiaUnDimItem(dia, DFCL_THEVIEW);
8553 					}
8554 					break;
8555 			}
8556 			continue;
8557 		}
8558 		if (itemHit == DFCL_ALLCELLS || itemHit == DFCL_UNDERTHIS ||
8559 			itemHit == DFCL_INUSE || itemHit == DFCL_PLACEHOLDERS ||
8560 			itemHit == DFCL_NOTINUSE)
8561 		{
8562 			DiaSetControl(dia, DFCL_ALLCELLS, 0);
8563 			DiaSetControl(dia, DFCL_UNDERTHIS, 0);
8564 			DiaSetControl(dia, DFCL_INUSE, 0);
8565 			DiaSetControl(dia, DFCL_PLACEHOLDERS, 0);
8566 			DiaSetControl(dia, DFCL_NOTINUSE, 0);
8567 			DiaSetControl(dia, itemHit, 1);
8568 			which = itemHit;
8569 			continue;
8570 		}
8571 		if (itemHit == DFCL_BYNAME || itemHit == DFCL_BYDATE ||
8572 			itemHit == DFCL_BYSKELETON)
8573 		{
8574 			DiaSetControl(dia, DFCL_BYNAME, 0);
8575 			DiaSetControl(dia, DFCL_BYDATE, 0);
8576 			DiaSetControl(dia, DFCL_BYSKELETON, 0);
8577 			DiaSetControl(dia, itemHit, 1);
8578 			sortorder = itemHit;
8579 			continue;
8580 		}
8581 		if (itemHit == DFCL_TOMESSAGES || itemHit == DFCL_TODISK)
8582 		{
8583 			DiaSetControl(dia, DFCL_TOMESSAGES, 0);
8584 			DiaSetControl(dia, DFCL_TODISK, 0);
8585 			DiaSetControl(dia, itemHit, 1);
8586 			where = itemHit;
8587 			continue;
8588 		}
8589 	}
8590 	if (itemHit == OK)
8591 	{
8592 		/* mark cells to be shown */
8593 		if (DiaGetControl(dia, DFCL_ALLCELLS) != 0)
8594 		{
8595 			/* mark all cells for display */
8596 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8597 				for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8598 					np->temp1 = 1;
8599 		} else
8600 		{
8601 			/* mark no cells for display, filter according to request */
8602 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8603 				for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8604 					np->temp1 = 0;
8605 			if (DiaGetControl(dia, DFCL_UNDERTHIS) != 0)
8606 			{
8607 				/* mark those that are under this */
8608 				if (curf != NONODEPROTO) us_recursivemark(curf);
8609 			} else if (DiaGetControl(dia, DFCL_INUSE) != 0)
8610 			{
8611 				/* mark those that are in use */
8612 				for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8613 				{
8614 					for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8615 					{
8616 						inp = iconview(np);
8617 						if (inp == NONODEPROTO) inp = np;
8618 						if (inp->firstinst != NONODEINST || np->firstinst != NONODEINST) np->temp1 = 1;
8619 					}
8620 				}
8621 			} else if (DiaGetControl(dia, DFCL_NOTINUSE) != 0)
8622 			{
8623 				/* mark those that are not in use */
8624 				for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8625 				{
8626 					for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8627 					{
8628 						inp = iconview(np);
8629 						if (inp != NONODEPROTO)
8630 						{
8631 							/* has icon: acceptable if the only instances are examples */
8632 							if (np->firstinst != NONODEINST) continue;
8633 							for(ni = inp->firstinst; ni != NONODEINST; ni = ni->nextinst)
8634 								if (!isiconof(inp, ni->parent)) break;
8635 							if (ni != NONODEINST) continue;
8636 						} else
8637 						{
8638 							/* no icon: reject if this has instances */
8639 							if (np->cellview == el_iconview)
8640 							{
8641 								/* this is an icon: reject if instances are not examples */
8642 								for(ni = np->firstinst; ni != NONODEINST; ni = ni->nextinst)
8643 									if (!isiconof(np, ni->parent)) break;
8644 								if (ni != NONODEINST) continue;
8645 							} else
8646 							{
8647 								if (np->firstinst != NONODEINST) continue;
8648 							}
8649 						}
8650 						np->temp1 = 1;
8651 					}
8652 				}
8653 			} else
8654 			{
8655 				/* mark placeholder cells */
8656 				for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8657 				{
8658 					for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8659 					{
8660 						var = getval((INTBIG)np, VNODEPROTO, VSTRING, x_("IO_true_library"));
8661 						if (var != NOVARIABLE) np->temp1 = 1;
8662 					}
8663 				}
8664 			}
8665 		}
8666 
8667 		/* filter views */
8668 		if (DiaGetControl(dia, DFCL_ONEVIEW) != 0)
8669 		{
8670 			i = DiaGetPopupEntry(dia, DFCL_THEVIEW);
8671 			v = getview(viewlist[i]);
8672 			if (v != NOVIEW)
8673 			{
8674 				for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8675 				{
8676 					for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8677 					{
8678 						if (np->cellview != v)
8679 						{
8680 							if (np->cellview == el_iconview)
8681 							{
8682 								if (DiaGetControl(dia, DFCL_ICONSVIEWS) != 0) continue;
8683 							}
8684 							np->temp1 = 0;
8685 						}
8686 					}
8687 				}
8688 			}
8689 		}
8690 
8691 		/* filter versions */
8692 		if (DiaGetControl(dia, DFCL_NOOLDVERS) != 0)
8693 		{
8694 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8695 			{
8696 				for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8697 				{
8698 					if (np->newestversion != np) np->temp1 = 0;
8699 				}
8700 			}
8701 		}
8702 		if (DiaGetControl(dia, DFCL_NONEWVERS) != 0)
8703 		{
8704 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8705 			{
8706 				for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8707 				{
8708 					if (np->newestversion == np) np->temp1 = 0;
8709 				}
8710 			}
8711 		}
8712 
8713 		/* now make a list and sort it */
8714 		total = 0;
8715 		for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8716 		{
8717 			if ((lib->userbits&HIDDENLIBRARY) != 0) continue;
8718 			for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8719 			{
8720 				if (np->temp1 != 0) total++;
8721 			}
8722 		}
8723 		if (total == 0) ttyputmsg(_("No cells match this request")); else
8724 		{
8725 			nplist = (NODEPROTO **)emalloc(total * (sizeof (NODEPROTO *)), el_tempcluster);
8726 			if (nplist == 0) return(0);
8727 			total = 0;
8728 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
8729 			{
8730 				if ((lib->userbits&HIDDENLIBRARY) != 0) continue;
8731 				for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8732 				{
8733 					if (np->temp1 != 0) nplist[total++] = np;
8734 				}
8735 			}
8736 			if (DiaGetControl(dia, DFCL_BYNAME) != 0)
8737 			{
8738 				esort(nplist, total, sizeof (NODEPROTO *), us_sortbycellname);
8739 			} else if (DiaGetControl(dia, DFCL_BYDATE) != 0)
8740 			{
8741 				esort(nplist, total, sizeof (NODEPROTO *), us_sortbycelldate);
8742 			} else if (DiaGetControl(dia, DFCL_BYSKELETON) != 0)
8743 			{
8744 				esort(nplist, total, sizeof (NODEPROTO *), us_sortbyskeletonstructure);
8745 			}
8746 
8747 			/* finally show the results */
8748 			if (DiaGetControl(dia, DFCL_TODISK) != 0)
8749 			{
8750 				dumpfile = xcreate(x_("celllist.txt"), el_filetypetext, _("Cell Listing File:"), &truename);
8751 				if (dumpfile == 0) ttyputerr(_("Cannot write cell listing")); else
8752 				{
8753 					efprintf(dumpfile, _("List of cells created on %s\n"), timetostring(getcurrenttime()));
8754 					efprintf(dumpfile, _("Cell\tVersion\tCreation date\tRevision Date\tSize\tUsage\tLock\tInst-lock\tCell-lib\tDRC\tNCC\n"));
8755 					for(i=0; i<total; i++)
8756 						efprintf(dumpfile, x_("%s\n"), us_makecellline(nplist[i], -1));
8757 					xclose(dumpfile);
8758 					ttyputmsg(_("Wrote %s"), truename);
8759 				}
8760 			} else
8761 			{
8762 				maxlen = 0;
8763 				for(i=0; i<total; i++)
8764 					maxlen = maxi(maxlen, estrlen(nldescribenodeproto(nplist[i])));
8765 				maxlen = maxi(maxlen+2, 7);
8766 				infstr = initinfstr();
8767 				addstringtoinfstr(infstr, _("Cell"));
8768 				for(i=4; i<maxlen; i++) addtoinfstr(infstr, '-');
8769 				addstringtoinfstr(infstr, _("Version-----Creation date"));
8770 				addstringtoinfstr(infstr, _("---------Revision Date------------Size-------Usage-L-I-C-D-N"));
8771 				ttyputmsg(x_("%s"), returninfstr(infstr));
8772 				lib = NOLIBRARY;
8773 				for(i=0; i<total; i++)
8774 				{
8775 					if (nplist[i]->lib != lib)
8776 					{
8777 						lib = nplist[i]->lib;
8778 						ttyputmsg(_("======== LIBRARY %s: ========"), lib->libname);
8779 					}
8780 					savelib = el_curlib;
8781 					el_curlib = lib;
8782 					ttyputmsg(x_("%s"), us_makecellline(nplist[i], maxlen));
8783 					el_curlib = lib;
8784 				}
8785 			}
8786 		}
8787 	}
8788 	DiaDoneDialog(dia);
8789 	efree((CHAR *)viewlist);
8790 	return(1);
8791 }
8792 
8793 /*
8794  * Helper routine for "esort" that makes cells go by skeleton structure
8795  */
us_sortbyskeletonstructure(const void * e1,const void * e2)8796 int us_sortbyskeletonstructure(const void *e1, const void *e2)
8797 {
8798 	REGISTER NODEPROTO *f1, *f2;
8799 	REGISTER INTBIG xs1, xs2, ys1, ys2, pc1, pc2;
8800 	INTBIG x1, y1, x2, y2;
8801 	REGISTER PORTPROTO *pp1, *pp2;
8802 	NODEINST dummyni;
8803 	REGISTER NODEINST *ni;
8804 
8805 	f1 = *((NODEPROTO **)e1);
8806 	f2 = *((NODEPROTO **)e2);
8807 
8808 	/* first sort by cell size */
8809 	xs1 = f1->highx - f1->lowx;   xs2 = f2->highx - f2->lowx;
8810 	if (xs1 != xs2) return(xs1-xs2);
8811 	ys1 = f1->highy - f1->lowy;   ys2 = f2->highy - f2->lowy;
8812 	if (ys1 != ys2) return(ys1-ys2);
8813 
8814 	/* now sort by number of exports */
8815 	pc1 = 0;
8816 	for(pp1 = f1->firstportproto; pp1 != NOPORTPROTO; pp1 = pp1->nextportproto) pc1++;
8817 	pc2 = 0;
8818 	for(pp2 = f2->firstportproto; pp2 != NOPORTPROTO; pp2 = pp2->nextportproto) pc2++;
8819 	if (pc1 != pc2) return(pc1-pc2);
8820 
8821 	/* now match the exports */
8822 	for(pp1 = f1->firstportproto; pp1 != NOPORTPROTO; pp1 = pp1->nextportproto) pp1->temp1 = 0;
8823 	for(pp2 = f2->firstportproto; pp2 != NOPORTPROTO; pp2 = pp2->nextportproto)
8824 	{
8825 		/* locate center of this export */
8826 		ni = &dummyni;
8827 		initdummynode(ni);
8828 		ni->proto = f2;
8829 		ni->lowx = -xs1/2;   ni->highx = ni->lowx + xs1;
8830 		ni->lowy = -ys1/2;   ni->highy = ni->lowy + ys1;
8831 		portposition(ni, pp2, &x2, &y2);
8832 
8833 		ni->proto = f1;
8834 		for(pp1 = f1->firstportproto; pp1 != NOPORTPROTO; pp1 = pp1->nextportproto)
8835 		{
8836 			portposition(ni, pp1, &x1, &y1);
8837 			if (x1 == x2 && y1 == y2) break;
8838 		}
8839 		if (pp1 == NOPORTPROTO) return(f1-f2);
8840 		pp1->temp1 = 1;
8841 	}
8842 	for(pp1 = f1->firstportproto; pp1 != NOPORTPROTO; pp1 = pp1->nextportproto)
8843 		if (pp1->temp1 == 0) return(f1-f2);
8844 	return(0);
8845 }
8846 
8847 /*
8848  * Helper routine for "esort" that makes cells go by date
8849  */
us_sortbycelldate(const void * e1,const void * e2)8850 int us_sortbycelldate(const void *e1, const void *e2)
8851 {
8852 	REGISTER NODEPROTO *f1, *f2;
8853 	REGISTER UINTBIG r1, r2;
8854 
8855 	f1 = *((NODEPROTO **)e1);
8856 	f2 = *((NODEPROTO **)e2);
8857 	r1 = f1->revisiondate;
8858 	r2 = f2->revisiondate;
8859 	if (r1 == r2) return(0);
8860 	if (r1 < r2) return(-(int)(r2-r1));
8861 	return(r1-r2);
8862 }
8863 
8864 /*
8865  * Helper routine for "esort" that makes cell names be ascending
8866  */
us_sortbycellname(const void * e1,const void * e2)8867 int us_sortbycellname(const void *e1, const void *e2)
8868 {
8869 	REGISTER NODEPROTO *f1, *f2;
8870 	REGISTER void *infstr;
8871 	REGISTER CHAR *s1, *s2;
8872 
8873 	f1 = *((NODEPROTO **)e1);
8874 	f2 = *((NODEPROTO **)e2);
8875 	infstr = initinfstr();
8876 	formatinfstr(infstr, x_("%s:%s"), f1->lib->libname, nldescribenodeproto(f1));
8877 	s1 = returninfstr(infstr);
8878 	infstr = initinfstr();
8879 	formatinfstr(infstr, x_("%s:%s"), f2->lib->libname, nldescribenodeproto(f2));
8880 	s2 = returninfstr(infstr);
8881 	return(namesame(s1, s2));
8882 }
8883 
8884 /****************************** CELL SELECTION DIALOGS ******************************/
8885 
8886 /* Cell Selection */
8887 static DIALOGITEM us_cellselectdialogitems[] =
8888 {
8889  /*  1 */ {0, {336,208,360,272}, BUTTON, N_("OK")},
8890  /*  2 */ {0, {336,16,360,80}, BUTTON, N_("Cancel")},
8891  /*  3 */ {0, {36,8,251,280}, SCROLL, x_("")},
8892  /*  4 */ {0, {284,8,302,153}, CHECK, N_("Show old versions")},
8893  /*  5 */ {0, {308,8,326,253}, CHECK, N_("Show cells from Cell-Library")},
8894  /*  6 */ {0, {8,8,26,67}, MESSAGE, N_("Library:")},
8895  /*  7 */ {0, {8,72,26,280}, POPUP, x_("")},
8896  /*  8 */ {0, {260,8,278,205}, CHECK, N_("Show relevant cells only")}
8897 };
8898 static DIALOG us_cellselectdialog = {{50,75,419,365}, N_("Cell List"), 0, 8, us_cellselectdialogitems, 0, 0};
8899 
8900 /*
8901  * special items for the "Delete Cell", "New Cell Instance", "List Cell Usage", and
8902  * "plot simulation in cell window" dialogs:
8903  */
8904 #define DFCS_CELLLIST        3		/* Cell list (message) */
8905 #define DFCS_OLDVERSIONS     4		/* Show old versions (check) */
8906 #define DFCS_CELLLIBRARIES   5		/* Show cell-library cells (check) */
8907 #define DFCS_LIBRARYLIST     7		/* List of libraries (popup) */
8908 #define DFCS_RELEVANTCELLS   8		/* Show relevant cells (check) */
8909 
8910 /*
8911  * Routine to present a cell list with the title "prompt".
8912  * If "selcell" is 0, choose a cell (including the current cell).
8913  * If "selcell" is 1, choose a cell for instance placement (doesn't include current cell).
8914  * If "selcell" is 2, choose a cell for deletion (actually, do deletion dialog).
8915  */
us_cellselect(CHAR * prompt,CHAR * paramstart[],INTBIG selcell)8916 INTBIG us_cellselect(CHAR *prompt, CHAR *paramstart[], INTBIG selcell)
8917 {
8918 	REGISTER INTBIG itemHit, libindex;
8919 	INTBIG i, librarycount;
8920 	REGISTER CHAR **librarylist;
8921 	CHAR *arglist[1], *pt;
8922 	REGISTER NODEPROTO *np;
8923 	REGISTER BOOLEAN curinstance, curcell;
8924 	REGISTER void *infstr, *dia;
8925 
8926 	/* display the dialog box */
8927 	us_cellselectdialog.movable = prompt;
8928 	if (selcell != 2)
8929 	{
8930 		/* cell selection */
8931 		us_cellselectdialogitems[0].msg = _("OK");
8932 		us_cellselectdialogitems[1].msg = _("Cancel");
8933 		curinstance = TRUE;
8934 		if (selcell == 0) curcell = TRUE; else
8935 			curcell = FALSE;
8936 	} else
8937 	{
8938 		/* cell deletion */
8939 		us_cellselectdialogitems[0].msg = _("Delete");
8940 		us_cellselectdialogitems[1].msg = _("Done");
8941 		curinstance = FALSE;
8942 		curcell = TRUE;
8943 	}
8944 	dia = DiaInitDialog(&us_cellselectdialog);
8945 	if (dia == 0) return(0);
8946 	us_showoldversions = us_defshowoldversions;
8947 	us_showcellibrarycells = us_defshowcellibrarycells;
8948 	us_showonlyrelevantcells = us_defshowonlyrelevantcells;
8949 	us_curlib = el_curlib;
8950 	DiaInitTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells, us_oldcellnextcells,
8951 		DiaNullDlogDone, 0, SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT);
8952 	(void)us_setscrolltocurrentcell(DFCS_CELLLIST, curinstance, curcell, FALSE, FALSE, dia);
8953 	if (us_showonlyrelevantcells != 0) DiaSetControl(dia, DFCS_RELEVANTCELLS, 1);
8954 
8955 	/* make a list of library names */
8956 	librarylist = us_makelibrarylist(&librarycount, us_curlib, &i);
8957 	libindex = 0;
8958 	for(i=0; i<librarycount; i++)
8959 		if (namesame(librarylist[i], us_curlib->libname) == 0) libindex = i;
8960 	DiaSetPopup(dia, DFCS_LIBRARYLIST, librarycount, librarylist);
8961 	DiaSetPopupEntry(dia, DFCS_LIBRARYLIST, libindex);
8962 
8963 	/* see if there are any old versions */
8964 	for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8965 		if (np->newestversion != np) break;
8966 	if (np == NONODEPROTO) DiaDimItem(dia, DFCS_OLDVERSIONS); else
8967 	{
8968 		DiaUnDimItem(dia, DFCS_OLDVERSIONS);
8969 		DiaSetControl(dia, DFCS_OLDVERSIONS, us_showoldversions);
8970 	}
8971 
8972 	/* see if there are any cell-library cells */
8973 	for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
8974 		if ((np->userbits&INCELLLIBRARY) != 0) break;
8975 	if (np == NONODEPROTO) DiaDimItem(dia, DFCS_CELLLIBRARIES); else
8976 	{
8977 		DiaUnDimItem(dia, DFCS_CELLLIBRARIES);
8978 		DiaSetControl(dia, DFCS_CELLLIBRARIES, us_showcellibrarycells);
8979 	}
8980 
8981 	for(;;)
8982 	{
8983 		itemHit = DiaNextHit(dia);
8984 		if (itemHit == CANCEL) break;
8985 		if (itemHit == OK)
8986 		{
8987 			if (selcell != 2) break;
8988 
8989 			/* delete the cell */
8990 			infstr = initinfstr();
8991 			if (us_curlib != el_curlib)
8992 			{
8993 				addstringtoinfstr(infstr, us_curlib->libname);
8994 				addtoinfstr(infstr, ':');
8995 			}
8996 			i = DiaGetCurLine(dia, DFCS_CELLLIST);
8997 			addstringtoinfstr(infstr, DiaGetScrollLine(dia, DFCS_CELLLIST, i));
8998 			(void)allocstring(&pt, returninfstr(infstr), el_tempcluster);
8999 			arglist[0] = pt;
9000 			us_killcell(1, arglist);
9001 			efree((CHAR *)pt);
9002 			DiaLoadTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells, us_oldcellnextcells,
9003 				DiaNullDlogDone, 0);
9004 			if (*DiaGetScrollLine(dia, DFCS_CELLLIST, i) == 0) i--;
9005 			DiaSelectLine(dia, DFCS_CELLLIST, i);
9006 			continue;
9007 		}
9008 		if (itemHit == DFCS_OLDVERSIONS)
9009 		{
9010 			us_defshowoldversions = us_showoldversions = 1 - DiaGetControl(dia, DFCS_OLDVERSIONS);
9011 			DiaSetControl(dia, DFCS_OLDVERSIONS, us_showoldversions);
9012 			DiaLoadTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells,
9013 				us_oldcellnextcells, DiaNullDlogDone, 0);
9014 		}
9015 		if (itemHit == DFCS_CELLLIBRARIES)
9016 		{
9017 			us_defshowcellibrarycells = us_showcellibrarycells = 1 - DiaGetControl(dia, DFCS_CELLLIBRARIES);
9018 			DiaSetControl(dia, DFCS_CELLLIBRARIES, us_showcellibrarycells);
9019 			DiaLoadTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells,
9020 				us_oldcellnextcells, DiaNullDlogDone, 0);
9021 		}
9022 		if (itemHit == DFCS_RELEVANTCELLS)
9023 		{
9024 			us_defshowonlyrelevantcells = us_showonlyrelevantcells = 1 - DiaGetControl(dia, DFCS_RELEVANTCELLS);
9025 			DiaSetControl(dia, DFCS_RELEVANTCELLS, us_showonlyrelevantcells);
9026 			DiaLoadTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells,
9027 				us_oldcellnextcells, DiaNullDlogDone, 0);
9028 		}
9029 		if (itemHit == DFCS_LIBRARYLIST)
9030 		{
9031 			i = DiaGetPopupEntry(dia, DFCS_LIBRARYLIST);
9032 			us_curlib = getlibrary(librarylist[i]);
9033 			DiaInitTextDialog(dia, DFCS_CELLLIST, us_oldcelltopofcells,
9034 				us_oldcellnextcells, DiaNullDlogDone, 0, SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT);
9035 			(void)us_setscrolltocurrentcell(DFCS_CELLLIST, curinstance, curcell, FALSE, FALSE, dia);
9036 
9037 			/* see if there are any old versions */
9038 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9039 				if (np->newestversion != np) break;
9040 			if (np == NONODEPROTO) DiaDimItem(dia, DFCS_OLDVERSIONS); else
9041 			{
9042 				DiaUnDimItem(dia, DFCS_OLDVERSIONS);
9043 				DiaSetControl(dia, DFCS_OLDVERSIONS, us_showoldversions);
9044 			}
9045 
9046 			/* see if there are any cell-library cells */
9047 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9048 				if ((np->userbits&INCELLLIBRARY) != 0) break;
9049 			if (np == NONODEPROTO) DiaDimItem(dia, DFCS_CELLLIBRARIES); else
9050 			{
9051 				DiaUnDimItem(dia, DFCS_CELLLIBRARIES);
9052 				DiaSetControl(dia, DFCS_CELLLIBRARIES, us_showcellibrarycells);
9053 			}
9054 			continue;
9055 		}
9056 	}
9057 	if (selcell != 2)
9058 	{
9059 		infstr = initinfstr();
9060 		if (us_curlib != el_curlib)
9061 		{
9062 			addstringtoinfstr(infstr, us_curlib->libname);
9063 			addtoinfstr(infstr, ':');
9064 		}
9065 		addstringtoinfstr(infstr, DiaGetScrollLine(dia, DFCS_CELLLIST, DiaGetCurLine(dia, DFCS_CELLLIST)));
9066 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
9067 		allocstring(&us_returneddialogstring, returninfstr(infstr), us_tool->cluster);
9068 		paramstart[0] = us_returneddialogstring;
9069 	}
9070 	DiaDoneDialog(dia);
9071 	if (itemHit == CANCEL) return(0);
9072 	return(1);
9073 }
9074 
9075 /****************************** CELL OPTIONS DIALOG ******************************/
9076 
9077 /* Cell options */
9078 static DIALOGITEM us_celldialogitems[] =
9079 {
9080  /*  1 */ {0, {288,512,312,576}, BUTTON, N_("OK")},
9081  /*  2 */ {0, {232,512,256,576}, BUTTON, N_("Cancel")},
9082  /*  3 */ {0, {304,24,320,324}, CHECK, N_("Tiny cell instances hashed out")},
9083  /*  4 */ {0, {8,8,24,90}, MESSAGE, N_("Library:")},
9084  /*  5 */ {0, {28,4,188,150}, SCROLL, x_("")},
9085  /*  6 */ {0, {8,92,24,256}, POPUP, x_("")},
9086  /*  7 */ {0, {196,4,197,584}, DIVIDELINE, x_("")},
9087  /*  8 */ {0, {208,4,224,116}, MESSAGE, N_("For all cells:")},
9088  /*  9 */ {0, {28,156,44,496}, CHECK, N_("Disallow modification of anything in this cell")},
9089  /* 10 */ {0, {4,500,20,584}, MESSAGE, N_("Every cell:")},
9090  /* 11 */ {0, {52,156,68,496}, CHECK, N_("Disallow modification of instances in this cell")},
9091  /* 12 */ {0, {148,156,164,344}, MESSAGE|INACTIVE, N_("Characteristic X Spacing:")},
9092  /* 13 */ {0, {172,156,188,344}, MESSAGE|INACTIVE, N_("Characteristic Y Spacing:")},
9093  /* 14 */ {0, {148,348,164,424}, EDITTEXT, x_("")},
9094  /* 15 */ {0, {172,348,188,424}, EDITTEXT, x_("")},
9095  /* 16 */ {0, {76,156,92,496}, CHECK, N_("Part of a cell-library")},
9096  /* 17 */ {0, {76,500,92,536}, BUTTON, N_("Set")},
9097  /* 18 */ {0, {76,544,92,584}, BUTTON, N_("Clear")},
9098  /* 19 */ {0, {328,24,344,280}, MESSAGE|INACTIVE, N_("Hash cells when scale is more than:")},
9099  /* 20 */ {0, {328,284,344,344}, EDITTEXT, x_("")},
9100  /* 21 */ {0, {328,348,344,472}, MESSAGE|INACTIVE, N_("lambda per pixel")},
9101  /* 22 */ {0, {124,156,140,344}, RADIO, N_("Expand new instances")},
9102  /* 23 */ {0, {124,360,140,548}, RADIO, N_("Unexpand new instances")},
9103  /* 24 */ {0, {232,24,248,324}, CHECK, N_("Check cell dates during creation")},
9104  /* 25 */ {0, {28,544,44,584}, BUTTON, N_("Clear")},
9105  /* 26 */ {0, {28,500,44,536}, BUTTON, N_("Set")},
9106  /* 27 */ {0, {52,544,68,584}, BUTTON, N_("Clear")},
9107  /* 28 */ {0, {52,500,68,536}, BUTTON, N_("Set")},
9108  /* 29 */ {0, {256,24,272,324}, CHECK, N_("Switch technology to match current cell")},
9109  /* 30 */ {0, {352,24,368,280}, MESSAGE|INACTIVE, N_("Cell explorer text size:")},
9110  /* 31 */ {0, {352,284,368,344}, EDITTEXT, x_("")},
9111  /* 32 */ {0, {280,24,296,324}, CHECK, N_("Place Cell-Center in new cells")},
9112  /* 33 */ {0, {100,156,116,496}, CHECK, N_("Use technology editor on this cell")},
9113  /* 34 */ {0, {100,500,116,536}, BUTTON, N_("Set")},
9114  /* 35 */ {0, {100,544,116,584}, BUTTON, N_("Clear")}
9115 };
9116 static DIALOG us_celldialog = {{50,75,427,669}, N_("Cell Options"), 0, 35, us_celldialogitems, 0, 0};
9117 
9118 /* special items for the "cell info" dialog: */
9119 #define DFCO_TINYCELLGREY           3		/* Tiny cells (check) */
9120 #define DFCO_CELLLIST               5		/* Cell names (scroll) */
9121 #define DFCO_LIBRARYLIST            6		/* Library to use (popup) */
9122 #define DFCO_ALLOWALLMODCELL        9		/* Allow all mod in cell (check) */
9123 #define DFCO_ALLOWINSTMODCELL      11		/* Allow inst mod in cell (check) */
9124 #define DFCO_CHARSPACX             14		/* X Characteristic spacing (edit text) */
9125 #define DFCO_CHARSPACY             15		/* Y Characteristic spacing (edit text) */
9126 #define DFCO_CELLLIBRARY           16		/* Part of cell library (check) */
9127 #define DFCO_CELLLIBRARYSET        17		/* "Set all" for cell library (button) */
9128 #define DFCO_CELLLIBRARYCLR        18		/* "Clear all" for cell library (button) */
9129 #define DFCO_TINYCELLTHRESH        20		/* Tiny lambda per pixel (edit text) */
9130 #define DFCO_EXPANDINST            22		/* Expand new instances (radio) */
9131 #define DFCO_UNEXPANDINST          23		/* Unexpand new instances (radio) */
9132 #define DFCO_CHECKDATES            24		/* Check dates (check) */
9133 #define DFCO_ALLOWALLMODCELLCLR    25		/* "Clear all" for cell modification (button) */
9134 #define DFCO_ALLOWALLMODCELLSET    26		/* "Set all" for cell modification (button) */
9135 #define DFCO_ALLOWINSTMODCELLCLR   27		/* "Clear all" for instance modification (button) */
9136 #define DFCO_ALLOWINSTMODCELLSET   28		/* "Set all" for instance modification (button) */
9137 #define DFCO_AUTOTECHSWITCH        29		/* Switch technology when cell changes (check) */
9138 #define DFCO_EXPLORERTEXTSIZE      31		/* Cell explorer text size (edit text) */
9139 #define DFCO_PLACECELLCENTER       32		/* Place cell-center in new cells (check) */
9140 #define DFCO_USETECHEDIT           33		/* Use technology editor on this cell (check) */
9141 #define DFCO_USETECHEDITSET        34		/* "Set all" for technology editor use (button) */
9142 #define DFCO_USETECHEDITCLR        35		/* "Clear all" for technology editor use (button) */
9143 
us_celldlog(void)9144 INTBIG us_celldlog(void)
9145 {
9146 	INTBIG itemHit, i, lx, total, value, exploretextsize;
9147 	CHAR buf[20];
9148 	REGISTER NODEPROTO *thiscell, *np;
9149 	REGISTER VARIABLE *var;
9150 	REGISTER LIBRARY *lib, *savelib;
9151 	REGISTER CHAR *pt, **liblist;
9152 	typedef struct
9153 	{
9154 		INTBIG newbits;
9155 		INTBIG validcharacteristicspacing;
9156 		INTBIG characteristicspacing[2];
9157 	} CELLINFO;
9158 	CELLINFO *fi;
9159 	REGISTER void *dia;
9160 
9161 	/* display the cell dialog box */
9162 	dia = DiaInitDialog(&us_celldialog);
9163 	if (dia == 0) return(0);
9164 
9165 	/* show the cells in this library */
9166 	us_showoldversions = 1;
9167 	us_showcellibrarycells = 1;
9168 	us_showonlyrelevantcells = 0;
9169 	us_curlib = el_curlib;
9170 	DiaInitTextDialog(dia, DFCO_CELLLIST, us_oldcelltopofcells, us_oldcellnextcells,
9171 		DiaNullDlogDone, 0, SCSELMOUSE|SCSELKEY|SCREPORT);
9172 
9173 	/* get the current cell, and set the scroll item to it */
9174 	thiscell = us_setscrolltocurrentcell(DFCO_CELLLIST, FALSE, TRUE, TRUE, FALSE, dia);
9175 	if (thiscell != NONODEPROTO && thiscell->lib != us_curlib)
9176 		thiscell = NONODEPROTO;
9177 	if (thiscell == NONODEPROTO) thiscell = us_curlib->firstnodeproto;
9178 
9179 	/* load popup of libraries */
9180 	liblist = us_makelibrarylist(&total, us_curlib, &i);
9181 	DiaSetPopup(dia, DFCO_LIBRARYLIST, total, liblist);
9182 	if (i >= 0) DiaSetPopupEntry(dia, DFCO_LIBRARYLIST, i);
9183 
9184 	/* save cell information */
9185 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
9186 		for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9187 	{
9188 		fi = (CELLINFO *)emalloc(sizeof (CELLINFO), el_tempcluster);
9189 		if (fi == 0) return(0);
9190 		fi->newbits = np->userbits;
9191 		var = getval((INTBIG)np, VNODEPROTO, VINTEGER|VISARRAY, x_("FACET_characteristic_spacing"));
9192 		if (var == NOVARIABLE) fi->validcharacteristicspacing = 0; else
9193 		{
9194 			fi->characteristicspacing[0] = ((INTBIG *)var->addr)[0];
9195 			fi->characteristicspacing[1] = ((INTBIG *)var->addr)[1];
9196 			fi->validcharacteristicspacing = 1;
9197 		}
9198 		np->temp1 = (INTBIG)fi;
9199 	}
9200 
9201 	/* load defaults for primitives and cells */
9202 	if (thiscell != NONODEPROTO)
9203 	{
9204 		DiaUnDimItem(dia, DFCO_CELLLIST);
9205 		DiaUnDimItem(dia, DFCO_ALLOWALLMODCELL);
9206 		DiaUnDimItem(dia, DFCO_ALLOWINSTMODCELL);
9207 		DiaUnDimItem(dia, DFCO_CHARSPACX);
9208 		DiaUnDimItem(dia, DFCO_CHARSPACY);
9209 		DiaUnDimItem(dia, DFCO_CELLLIBRARY);
9210 		DiaUnDimItem(dia, DFCO_CELLLIBRARYSET);
9211 		DiaUnDimItem(dia, DFCO_CELLLIBRARYCLR);
9212 		DiaUnDimItem(dia, DFCO_USETECHEDIT);
9213 		DiaUnDimItem(dia, DFCO_USETECHEDITSET);
9214 		DiaUnDimItem(dia, DFCO_USETECHEDITCLR);
9215 		DiaUnDimItem(dia, DFCO_EXPANDINST);
9216 		DiaUnDimItem(dia, DFCO_UNEXPANDINST);
9217 		DiaUnDimItem(dia, DFCO_ALLOWALLMODCELLCLR);
9218 		DiaUnDimItem(dia, DFCO_ALLOWALLMODCELLSET);
9219 		DiaUnDimItem(dia, DFCO_ALLOWINSTMODCELLCLR);
9220 		DiaUnDimItem(dia, DFCO_ALLOWINSTMODCELLSET);
9221 
9222 		fi = (CELLINFO *)thiscell->temp1;
9223 		if ((fi->newbits&NPLOCKED) != 0) DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 1); else
9224 			DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 0);
9225 		if ((fi->newbits&NPILOCKED) != 0) DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 1); else
9226 			DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 0);
9227 		if ((fi->newbits&INCELLLIBRARY) != 0) DiaSetControl(dia, DFCO_CELLLIBRARY, 1); else
9228 			DiaSetControl(dia, DFCO_CELLLIBRARY, 0);
9229 		if ((fi->newbits&TECEDITCELL) != 0) DiaSetControl(dia, DFCO_USETECHEDIT, 1); else
9230 			DiaSetControl(dia, DFCO_USETECHEDIT, 0);
9231 		if ((fi->newbits&WANTNEXPAND) != 0) DiaSetControl(dia, DFCO_EXPANDINST, 1); else
9232 			DiaSetControl(dia, DFCO_UNEXPANDINST, 1);
9233 		if (fi->validcharacteristicspacing != 0)
9234 		{
9235 			DiaSetText(dia, DFCO_CHARSPACX, latoa(fi->characteristicspacing[0], 0));
9236 			DiaSetText(dia, DFCO_CHARSPACY, latoa(fi->characteristicspacing[1], 0));
9237 		}
9238 	} else
9239 	{
9240 		DiaDimItem(dia, DFCO_CELLLIST);
9241 		DiaDimItem(dia, DFCO_ALLOWALLMODCELL);
9242 		DiaDimItem(dia, DFCO_ALLOWINSTMODCELL);
9243 		DiaDimItem(dia, DFCO_CHARSPACX);
9244 		DiaDimItem(dia, DFCO_CHARSPACY);
9245 		DiaDimItem(dia, DFCO_CELLLIBRARY);
9246 		DiaDimItem(dia, DFCO_CELLLIBRARYSET);
9247 		DiaDimItem(dia, DFCO_CELLLIBRARYCLR);
9248 		DiaDimItem(dia, DFCO_USETECHEDIT);
9249 		DiaDimItem(dia, DFCO_USETECHEDITSET);
9250 		DiaDimItem(dia, DFCO_USETECHEDITCLR);
9251 		DiaDimItem(dia, DFCO_EXPANDINST);
9252 		DiaDimItem(dia, DFCO_UNEXPANDINST);
9253 		DiaDimItem(dia, DFCO_ALLOWALLMODCELLCLR);
9254 		DiaDimItem(dia, DFCO_ALLOWALLMODCELLSET);
9255 		DiaDimItem(dia, DFCO_ALLOWINSTMODCELLCLR);
9256 		DiaDimItem(dia, DFCO_ALLOWINSTMODCELLSET);
9257 	}
9258 
9259 	/* load defaults for all nodes */
9260 	DiaSetControl(dia, DFCO_TINYCELLGREY, (us_useroptions&DRAWTINYCELLS) == 0 ? 1 : 0);
9261 	DiaSetControl(dia, DFCO_CHECKDATES, (us_useroptions&CHECKDATE) != 0 ? 1 : 0);
9262 	DiaSetControl(dia, DFCO_AUTOTECHSWITCH, (us_useroptions&AUTOSWITCHTECHNOLOGY) != 0 ? 1 : 0);
9263 	DiaSetControl(dia, DFCO_PLACECELLCENTER, (us_useroptions&CELLCENTERALWAYS) != 0 ? 1 : 0);
9264 
9265 	DiaSetText(dia, DFCO_TINYCELLTHRESH, frtoa(us_tinyratio));
9266 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_facet_explorer_textsize"));
9267 	if (var == NOVARIABLE) exploretextsize = DEFAULTEXPLORERTEXTSIZE; else
9268 		exploretextsize = var->addr;
9269 	esnprintf(buf, 20, x_("%ld"), exploretextsize);
9270 	DiaSetText(dia, DFCO_EXPLORERTEXTSIZE, buf);
9271 
9272 	/* loop until done */
9273 	for(;;)
9274 	{
9275 		itemHit = DiaNextHit(dia);
9276 		if (itemHit == OK || itemHit == CANCEL) break;
9277 		if (itemHit == DFCO_LIBRARYLIST)
9278 		{
9279 			/* clicked on the library selection popup */
9280 			i = DiaGetPopupEntry(dia, DFCO_LIBRARYLIST);
9281 			for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
9282 				if (namesame(lib->libname, liblist[i]) == 0) break;
9283 			if (lib == NOLIBRARY) continue;
9284 			us_curlib = lib;
9285 			DiaLoadTextDialog(dia, DFCO_CELLLIST, us_oldcelltopofcells,
9286 				us_oldcellnextcells, DiaNullDlogDone, 0);
9287 
9288 			thiscell = us_setscrolltocurrentcell(DFCO_CELLLIST, FALSE, TRUE, TRUE, FALSE, dia);
9289 			if (thiscell != NONODEPROTO && thiscell->lib != us_curlib)
9290 				thiscell = NONODEPROTO;
9291 			if (thiscell == NONODEPROTO) thiscell = us_curlib->firstnodeproto;
9292 			itemHit = DFCO_CELLLIST;
9293 		}
9294 		if (itemHit == DFCO_CELLLIST)
9295 		{
9296 			/* clicked on cell name in scroll list */
9297 			i = DiaGetCurLine(dia, DFCO_CELLLIST);
9298 			if (i < 0) continue;
9299 			pt = DiaGetScrollLine(dia, DFCO_CELLLIST, i);
9300 			savelib = el_curlib;
9301 			el_curlib = us_curlib;
9302 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9303 				if (namesame(pt, describenodeproto(np)) == 0) break;
9304 			el_curlib = savelib;
9305 			thiscell = np;
9306 			if (thiscell == NONODEPROTO) continue;
9307 			fi = (CELLINFO *)thiscell->temp1;
9308 			if ((fi->newbits&NPLOCKED) != 0) DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 1); else
9309 				DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 0);
9310 			if ((fi->newbits&NPILOCKED) != 0) DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 1); else
9311 				DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 0);
9312 			if ((fi->newbits&INCELLLIBRARY) != 0) DiaSetControl(dia, DFCO_CELLLIBRARY, 1); else
9313 				DiaSetControl(dia, DFCO_CELLLIBRARY, 0);
9314 			if ((fi->newbits&TECEDITCELL) != 0) DiaSetControl(dia, DFCO_USETECHEDIT, 1); else
9315 				DiaSetControl(dia, DFCO_USETECHEDIT, 0);
9316 			if ((fi->newbits&WANTNEXPAND) != 0)
9317 			{
9318 				DiaSetControl(dia, DFCO_EXPANDINST, 1);
9319 				DiaSetControl(dia, DFCO_UNEXPANDINST, 0);
9320 			} else
9321 			{
9322 				DiaSetControl(dia, DFCO_EXPANDINST, 0);
9323 				DiaSetControl(dia, DFCO_UNEXPANDINST, 1);
9324 			}
9325 			if (fi->validcharacteristicspacing != 0)
9326 			{
9327 				DiaSetText(dia, DFCO_CHARSPACX, latoa(fi->characteristicspacing[0], 0));
9328 				DiaSetText(dia, DFCO_CHARSPACY, latoa(fi->characteristicspacing[1], 0));
9329 			} else
9330 			{
9331 				DiaSetText(dia, DFCO_CHARSPACX, x_(""));
9332 				DiaSetText(dia, DFCO_CHARSPACY, x_(""));
9333 			}
9334 			continue;
9335 		}
9336 		if (itemHit == DFCO_ALLOWALLMODCELL)
9337 		{
9338 			/* clicked on check: "Disallow modification of anything in this cell" */
9339 			if (thiscell == NONODEPROTO) continue;
9340 			fi = (CELLINFO *)thiscell->temp1;
9341 			value = 1 - DiaGetControl(dia, DFCO_ALLOWALLMODCELL);
9342 			DiaSetControl(dia, DFCO_ALLOWALLMODCELL, value);
9343 			if (value == 0) fi->newbits &= ~NPLOCKED; else
9344 				fi->newbits |= NPLOCKED;
9345 			continue;
9346 		}
9347 		if (itemHit == DFCO_ALLOWINSTMODCELL)
9348 		{
9349 			/* clicked on check: "Disallow modification of instances in this cell" */
9350 			if (thiscell == NONODEPROTO) continue;
9351 			fi = (CELLINFO *)thiscell->temp1;
9352 			value = 1 - DiaGetControl(dia, DFCO_ALLOWINSTMODCELL);
9353 			DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, value);
9354 			if (value == 0) fi->newbits &= ~NPILOCKED; else
9355 				fi->newbits |= NPILOCKED;
9356 			continue;
9357 		}
9358 		if (itemHit == DFCO_CELLLIBRARY)
9359 		{
9360 			/* clicked on check: "Part of a cell-library" */
9361 			if (thiscell == NONODEPROTO) continue;
9362 			fi = (CELLINFO *)thiscell->temp1;
9363 			value = 1 - DiaGetControl(dia, DFCO_CELLLIBRARY);
9364 			DiaSetControl(dia, DFCO_CELLLIBRARY, value);
9365 			if (value == 0) fi->newbits &= ~INCELLLIBRARY; else
9366 				fi->newbits |= INCELLLIBRARY;
9367 			continue;
9368 		}
9369 		if (itemHit == DFCO_USETECHEDIT)
9370 		{
9371 			/* clicked on check: "Use technology editor on this cell" */
9372 			if (thiscell == NONODEPROTO) continue;
9373 			fi = (CELLINFO *)thiscell->temp1;
9374 			value = 1 - DiaGetControl(dia, DFCO_USETECHEDIT);
9375 			DiaSetControl(dia, DFCO_USETECHEDIT, value);
9376 			if (value == 0) fi->newbits &= ~TECEDITCELL; else
9377 				fi->newbits |= TECEDITCELL;
9378 			continue;
9379 		}
9380 		if (itemHit == DFCO_EXPANDINST || itemHit == DFCO_UNEXPANDINST)
9381 		{
9382 			/* clicked on radio buttons: "Expand/Unexpand new instances" */
9383 			if (thiscell == NONODEPROTO) continue;
9384 			fi = (CELLINFO *)thiscell->temp1;
9385 			DiaSetControl(dia, DFCO_EXPANDINST, 0);
9386 			DiaSetControl(dia, DFCO_UNEXPANDINST, 0);
9387 			DiaSetControl(dia, itemHit, 1);
9388 			if (itemHit == DFCO_EXPANDINST) fi->newbits |= WANTNEXPAND; else
9389 				fi->newbits &= ~WANTNEXPAND;
9390 			continue;
9391 		}
9392 		if (itemHit == DFCO_CELLLIBRARYSET)
9393 		{
9394 			/* clicked on button "Set" for all cells to be "Part of a cell-library" */
9395 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9396 			{
9397 				fi = (CELLINFO *)np->temp1;
9398 				fi->newbits |= INCELLLIBRARY;
9399 			}
9400 			DiaSetControl(dia, DFCO_CELLLIBRARY, 1);
9401 			continue;
9402 		}
9403 		if (itemHit == DFCO_CELLLIBRARYCLR)
9404 		{
9405 			/* clicked on button "Clear" for all cells to be "Part of a cell-library" */
9406 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9407 			{
9408 				fi = (CELLINFO *)np->temp1;
9409 				fi->newbits &= ~INCELLLIBRARY;
9410 			}
9411 			DiaSetControl(dia, DFCO_CELLLIBRARY, 0);
9412 			continue;
9413 		}
9414 		if (itemHit == DFCO_USETECHEDITSET)
9415 		{
9416 			/* clicked on button "Set" for all cells to be "Use technology editor on this cell" */
9417 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9418 			{
9419 				fi = (CELLINFO *)np->temp1;
9420 				fi->newbits |= TECEDITCELL;
9421 			}
9422 			DiaSetControl(dia, DFCO_USETECHEDIT, 1);
9423 			continue;
9424 		}
9425 		if (itemHit == DFCO_USETECHEDITCLR)
9426 		{
9427 			/* clicked on button "Clear" for all cells to be "Use technology editor on this cell" */
9428 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9429 			{
9430 				fi = (CELLINFO *)np->temp1;
9431 				fi->newbits &= ~TECEDITCELL;
9432 			}
9433 			DiaSetControl(dia, DFCO_USETECHEDIT, 0);
9434 			continue;
9435 		}
9436 		if (itemHit == DFCO_ALLOWALLMODCELLCLR)
9437 		{
9438 			/* clicked on button "Clear" for all cells to be "Disallow modification of anything in this cell" */
9439 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9440 			{
9441 				fi = (CELLINFO *)np->temp1;
9442 				fi->newbits &= ~NPLOCKED;
9443 			}
9444 			DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 0);
9445 			continue;
9446 		}
9447 		if (itemHit == DFCO_ALLOWALLMODCELLSET)
9448 		{
9449 			/* clicked on button "Set" for all cells to be "Disallow modification of anything in this cell" */
9450 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9451 			{
9452 				fi = (CELLINFO *)np->temp1;
9453 				fi->newbits |= NPLOCKED;
9454 			}
9455 			DiaSetControl(dia, DFCO_ALLOWALLMODCELL, 1);
9456 			continue;
9457 		}
9458 		if (itemHit == DFCO_ALLOWINSTMODCELLCLR)
9459 		{
9460 			/* clicked on button "Clear" for all cells to be "Disallow modification of instances in this cell" */
9461 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9462 			{
9463 				fi = (CELLINFO *)np->temp1;
9464 				fi->newbits &= ~NPILOCKED;
9465 			}
9466 			DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 0);
9467 			continue;
9468 		}
9469 		if (itemHit == DFCO_ALLOWINSTMODCELLSET)
9470 		{
9471 			/* clicked on button "Set" for all cells to be "Disallow modification of instances in this cell" */
9472 			for(np = us_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9473 			{
9474 				fi = (CELLINFO *)np->temp1;
9475 				fi->newbits |= NPILOCKED;
9476 			}
9477 			DiaSetControl(dia, DFCO_ALLOWINSTMODCELL, 1);
9478 			continue;
9479 		}
9480 		if (itemHit == DFCO_CHARSPACX)
9481 		{
9482 			/* changed X coordinate of characteristic spacing */
9483 			if (thiscell == NONODEPROTO) continue;
9484 			fi = (CELLINFO *)thiscell->temp1;
9485 			pt = DiaGetText(dia, DFCO_CHARSPACX);
9486 			if (fi->validcharacteristicspacing == 0 && *pt == 0) continue;
9487 			if (fi->validcharacteristicspacing == 0)
9488 				fi->characteristicspacing[1] = 0;
9489 			fi->validcharacteristicspacing = 1;
9490 			fi->characteristicspacing[0] = atola(pt, 0);
9491 			continue;
9492 		}
9493 		if (itemHit == DFCO_CHARSPACY)
9494 		{
9495 			/* changed Y coordinate of characteristic spacing */
9496 			if (thiscell == NONODEPROTO) continue;
9497 			fi = (CELLINFO *)thiscell->temp1;
9498 			pt = DiaGetText(dia, DFCO_CHARSPACY);
9499 			if (fi->validcharacteristicspacing == 0 && *pt == 0) continue;
9500 			if (fi->validcharacteristicspacing == 0)
9501 				fi->characteristicspacing[0] = 0;
9502 			fi->validcharacteristicspacing = 1;
9503 			fi->characteristicspacing[1] = atola(pt, 0);
9504 			continue;
9505 		}
9506 		if (itemHit == DFCO_TINYCELLGREY || itemHit == DFCO_CHECKDATES ||
9507 			itemHit == DFCO_AUTOTECHSWITCH || itemHit == DFCO_PLACECELLCENTER)
9508 		{
9509 			/* clicked on a check box */
9510 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
9511 			continue;
9512 		}
9513 	}
9514 
9515 	if (itemHit != CANCEL)
9516 	{
9517 		/* handle cell changes */
9518 		for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
9519 			for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9520 		{
9521 			fi = (CELLINFO *)np->temp1;
9522 			if ((fi->newbits&(NPLOCKED|NPILOCKED|INCELLLIBRARY|WANTNEXPAND|TECEDITCELL)) !=
9523 				(INTBIG)(np->userbits&(NPLOCKED|NPILOCKED|INCELLLIBRARY|WANTNEXPAND|TECEDITCELL)))
9524 					(void)setval((INTBIG)np, VNODEPROTO, x_("userbits"), fi->newbits, VINTEGER);
9525 			if (fi->validcharacteristicspacing != 0)
9526 				setval((INTBIG)np, VNODEPROTO, x_("FACET_characteristic_spacing"),
9527 					(INTBIG)fi->characteristicspacing, VINTEGER|VISARRAY|(2<<VLENGTHSH));
9528 		}
9529 
9530 		/* handle changes to all nodes */
9531 		startobjectchange((INTBIG)us_tool, VTOOL);
9532 		lx = us_useroptions;
9533 		i = DiaGetControl(dia, DFCO_TINYCELLGREY);
9534 		if (i == 0) lx |= DRAWTINYCELLS; else lx &= ~DRAWTINYCELLS;
9535 		i = DiaGetControl(dia, DFCO_CHECKDATES);
9536 		if (i != 0) lx |= CHECKDATE; else lx &= ~CHECKDATE;
9537 		i = DiaGetControl(dia, DFCO_AUTOTECHSWITCH);
9538 		if (i != 0) lx |= AUTOSWITCHTECHNOLOGY; else lx &= ~AUTOSWITCHTECHNOLOGY;
9539 		i = DiaGetControl(dia, DFCO_PLACECELLCENTER);
9540 		if (i != 0) lx |= CELLCENTERALWAYS; else lx &= ~CELLCENTERALWAYS;
9541 		if (lx != us_useroptions)
9542 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, lx, VINTEGER);
9543 		i = atofr(DiaGetText(dia, DFCO_TINYCELLTHRESH));
9544 		if (i != us_tinyratio)
9545 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_tinylambdaperpixelkey, i, VFRACT);
9546 		i = eatoi(DiaGetText(dia, DFCO_EXPLORERTEXTSIZE));
9547 		if (i != exploretextsize)
9548 		{
9549 			setval((INTBIG)us_tool, VTOOL, x_("USER_facet_explorer_textsize"), i, VINTEGER);
9550 			us_redoexplorerwindow();
9551 		}
9552 		endobjectchange((INTBIG)us_tool, VTOOL);
9553 	}
9554 	DiaDoneDialog(dia);
9555 	efree((CHAR *)liblist);
9556 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
9557 		for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
9558 			efree((CHAR *)np->temp1);
9559 	return(0);
9560 }
9561 
9562 /****************************** FIND TEXT DIALOG ******************************/
9563 
9564 /* Text: Search and Replace */
9565 static DIALOGITEM us_txtsardialogitems[] =
9566 {
9567  /*  1 */ {0, {92,4,116,72}, BUTTON, N_("Find")},
9568  /*  2 */ {0, {124,328,148,396}, BUTTON, N_("Done")},
9569  /*  3 */ {0, {92,84,116,152}, BUTTON, N_("Replace")},
9570  /*  4 */ {0, {8,76,24,396}, EDITTEXT, x_("")},
9571  /*  5 */ {0, {8,8,24,72}, MESSAGE, N_("Find:")},
9572  /*  6 */ {0, {36,76,52,396}, EDITTEXT, x_("")},
9573  /*  7 */ {0, {36,8,52,72}, MESSAGE, N_("Replace:")},
9574  /*  8 */ {0, {92,296,116,396}, BUTTON, N_("Replace All")},
9575  /*  9 */ {0, {64,216,80,344}, CHECK, N_("Find Reverse")},
9576  /* 10 */ {0, {64,80,80,208}, CHECK, N_("Case Sensitive")},
9577  /* 11 */ {0, {92,164,116,284}, BUTTON, N_("Replace and Find")},
9578  /* 12 */ {0, {128,4,144,96}, MESSAGE, N_("Line number:")},
9579  /* 13 */ {0, {128,100,144,180}, EDITTEXT, x_("")},
9580  /* 14 */ {0, {128,188,144,268}, BUTTON, N_("Go To Line")}
9581 };
9582 static DIALOG us_txtsardialog = {{75,75,232,481}, N_("Search and Replace"), 0, 14, us_txtsardialogitems, 0, 0};
9583 
9584 /* special items for the "Text Search and Replace" dialog: */
9585 #define DFDT_FIND             1		/* Find (button) */
9586 #define DFDT_DONE             2		/* Done (button) */
9587 #define DFDT_REPLACE          3		/* Replace (button) */
9588 #define DFDT_WHATTOFIND       4		/* Find text (edit text) */
9589 #define DFDT_WHATTOREPLACE    6		/* Replace text (edit text) */
9590 #define DFDT_REPLACEALL       8		/* Replace all (button) */
9591 #define DFDT_FINDREVERSE      9		/* Find reverse (check) */
9592 #define DFDT_CASESENSITIVE   10		/* Case sensitive (check) */
9593 #define DFDT_REPLACEANDFIND  11		/* Replace and Find (button) */
9594 #define DFDT_LINENUMBER_L    12		/* Line number label (message) */
9595 #define DFDT_LINENUMBER      13		/* Line number (edit text) */
9596 #define DFDT_GOTOLINE        14		/* Go To line (button) */
9597 
us_findtextdlog(void)9598 INTBIG us_findtextdlog(void)
9599 {
9600 	REGISTER INTBIG itemHit, bits, i, tot;
9601 	REGISTER BOOLEAN textsearch;
9602 	static INTBIG reversedir = 0;
9603 	static INTBIG casesensitive = 0;
9604 	REGISTER CHAR *sea, *rep, *pt;
9605 	CHAR line[100];
9606 	REGISTER void *dia;
9607 
9608 	if (us_needwindow()) return(0);
9609 	textsearch = TRUE;
9610 	if ((el_curwindowpart->state&WINDOWTYPE) != POPTEXTWINDOW &&
9611 		(el_curwindowpart->state&WINDOWTYPE) != TEXTWINDOW)
9612 			textsearch = FALSE;
9613 	dia = DiaInitDialog(&us_txtsardialog);
9614 	if (dia == 0) return(0);
9615 	if (us_lastfindtextmessage != 0)
9616 		DiaSetText(dia, DFDT_WHATTOFIND, us_lastfindtextmessage);
9617 	if (us_lastreplacetextmessage != 0)
9618 		DiaSetText(dia, DFDT_WHATTOREPLACE, us_lastreplacetextmessage);
9619 	if (casesensitive != 0) DiaSetControl(dia, DFDT_CASESENSITIVE, 1);
9620 	if (textsearch)
9621 	{
9622 		DiaUnDimItem(dia, DFDT_FINDREVERSE);
9623 		DiaUnDimItem(dia, DFDT_GOTOLINE);
9624 		DiaUnDimItem(dia, DFDT_LINENUMBER_L);
9625 		DiaUnDimItem(dia, DFDT_LINENUMBER);
9626 		if (reversedir != 0) DiaSetControl(dia, DFDT_FINDREVERSE, 1);
9627 	} else
9628 	{
9629 		DiaDimItem(dia, DFDT_FINDREVERSE);
9630 		DiaDimItem(dia, DFDT_GOTOLINE);
9631 		DiaDimItem(dia, DFDT_LINENUMBER_L);
9632 		DiaDimItem(dia, DFDT_LINENUMBER);
9633 		us_initsearchcircuittext(el_curwindowpart);
9634 	}
9635 	for(;;)
9636 	{
9637 		itemHit = DiaNextHit(dia);
9638 		if (itemHit == DFDT_DONE) break;
9639 		if (itemHit == DFDT_FIND)
9640 		{
9641 			/* find text */
9642 			sea = DiaGetText(dia, DFDT_WHATTOFIND);
9643 			bits = 0;
9644 			if (DiaGetControl(dia, DFDT_FINDREVERSE) != 0) bits |= 8;
9645 			if (DiaGetControl(dia, DFDT_CASESENSITIVE) != 0) bits |= 4;
9646 			if (textsearch) us_searchtext(el_curwindowpart, sea, 0, bits); else
9647 				us_searchcircuittext(el_curwindowpart, sea, 0, bits);
9648 			continue;
9649 		}
9650 		if (itemHit == DFDT_REPLACE)
9651 		{
9652 			/* replace text */
9653 			rep = DiaGetText(dia, DFDT_WHATTOREPLACE);
9654 			if (textsearch)
9655 			{
9656 				for(pt = rep; *pt != 0; pt++)
9657 					(void)us_gotchar(el_curwindowpart, *pt, 0);
9658 			} else
9659 			{
9660 				us_replacecircuittext(el_curwindowpart, rep);
9661 			}
9662 			continue;
9663 		}
9664 		if (itemHit == DFDT_REPLACEANDFIND)
9665 		{
9666 			/* replace and find text */
9667 			sea = DiaGetText(dia, DFDT_WHATTOFIND);
9668 			rep = DiaGetText(dia, DFDT_WHATTOREPLACE);
9669 			bits = 0;
9670 			if (DiaGetControl(dia, DFDT_FINDREVERSE) != 0) bits |= 8;
9671 			if (DiaGetControl(dia, DFDT_CASESENSITIVE) != 0) bits |= 4;
9672 			if (textsearch)
9673 			{
9674 				for(pt = rep; *pt != 0; pt++)
9675 					(void)us_gotchar(el_curwindowpart, *pt, 0);
9676 				us_searchtext(el_curwindowpart, sea, 0, bits);
9677 			} else
9678 			{
9679 				us_replacecircuittext(el_curwindowpart, rep);
9680 				us_searchcircuittext(el_curwindowpart, sea, 0, bits);
9681 			}
9682 			continue;
9683 		}
9684 		if (itemHit == DFDT_REPLACEALL)
9685 		{
9686 			/* replace all */
9687 			sea = DiaGetText(dia, DFDT_WHATTOFIND);
9688 			rep = DiaGetText(dia, DFDT_WHATTOREPLACE);
9689 			bits = 2;
9690 			if (DiaGetControl(dia, DFDT_FINDREVERSE) != 0) bits |= 8;
9691 			if (DiaGetControl(dia, DFDT_CASESENSITIVE) != 0) bits |= 4;
9692 			if (textsearch)
9693 				us_searchtext(el_curwindowpart, sea, rep, bits); else
9694 			{
9695 				us_initsearchcircuittext(el_curwindowpart);
9696 				us_searchcircuittext(el_curwindowpart, sea, rep, bits);
9697 			}
9698 			continue;
9699 		}
9700 		if (itemHit == DFDT_GOTOLINE)
9701 		{
9702 			/* go to line */
9703 			i = eatoi(DiaGetText(dia, DFDT_LINENUMBER)) - 1;
9704 			if (i < 0) continue;
9705 			tot = us_totallines(el_curwindowpart);
9706 			if (i > tot)
9707 			{
9708 				esnprintf(line, 100, x_("%ld"), tot);
9709 				DiaSetText(dia, DFDT_LINENUMBER, line);
9710 				continue;
9711 			}
9712 			us_highlightline(el_curwindowpart, i, i);
9713 			continue;
9714 		}
9715 		if (itemHit == DFDT_FINDREVERSE || itemHit == DFDT_CASESENSITIVE)
9716 		{
9717 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
9718 			if (!textsearch) us_initsearchcircuittext(el_curwindowpart);
9719 			continue;
9720 		}
9721 		if (itemHit == DFDT_WHATTOFIND)
9722 		{
9723 			if (!textsearch) us_initsearchcircuittext(el_curwindowpart);
9724 			continue;
9725 		}
9726 	}
9727 
9728 	/* save state for next use of this dialog */
9729 	if (us_lastfindtextmessage != 0) efree((CHAR *)us_lastfindtextmessage);
9730 	(void)allocstring(&us_lastfindtextmessage, DiaGetText(dia, DFDT_WHATTOFIND), us_tool->cluster);
9731 	if (us_lastreplacetextmessage != 0) efree((CHAR *)us_lastreplacetextmessage);
9732 	(void)allocstring(&us_lastreplacetextmessage, DiaGetText(dia, DFDT_WHATTOREPLACE), us_tool->cluster);
9733 	reversedir = DiaGetControl(dia, DFDT_FINDREVERSE);
9734 	casesensitive = DiaGetControl(dia, DFDT_CASESENSITIVE);
9735 
9736 	DiaDoneDialog(dia);
9737 	return(0);
9738 }
9739 
9740 /****************************** FRAME OPTIONS DIALOG ******************************/
9741 
9742 /* Drawing Options */
9743 static DIALOGITEM us_drawingoptdialogitems[] =
9744 {
9745  /*  1 */ {0, {48,456,72,520}, BUTTON, N_("OK")},
9746  /*  2 */ {0, {12,456,36,520}, BUTTON, N_("Cancel")},
9747  /*  3 */ {0, {116,4,132,112}, MESSAGE, N_("Company Name:")},
9748  /*  4 */ {0, {92,116,108,232}, MESSAGE, N_("Default:")},
9749  /*  5 */ {0, {140,4,156,112}, MESSAGE, N_("Designer Name:")},
9750  /*  6 */ {0, {164,4,180,112}, MESSAGE, N_("Project Name:")},
9751  /*  7 */ {0, {44,4,60,100}, MESSAGE, N_("Frame size:")},
9752  /*  8 */ {0, {44,104,60,220}, POPUP, x_("")},
9753  /*  9 */ {0, {32,228,48,324}, RADIO, N_("Landscape")},
9754  /* 10 */ {0, {56,228,72,324}, RADIO, N_("Portrait")},
9755  /* 11 */ {0, {8,4,24,404}, MESSAGE, N_("For cell:")},
9756  /* 12 */ {0, {116,116,132,316}, EDITTEXT, x_("")},
9757  /* 13 */ {0, {80,4,80,524}, DIVIDELINE, x_("")},
9758  /* 14 */ {0, {140,116,156,316}, EDITTEXT, x_("")},
9759  /* 15 */ {0, {164,116,180,316}, EDITTEXT, x_("")},
9760  /* 16 */ {0, {92,324,108,384}, MESSAGE, N_("Library:")},
9761  /* 17 */ {0, {92,384,108,524}, POPUP, x_("")},
9762  /* 18 */ {0, {116,324,132,524}, EDITTEXT, x_("")},
9763  /* 19 */ {0, {140,324,156,524}, EDITTEXT, x_("")},
9764  /* 20 */ {0, {164,324,180,524}, EDITTEXT, x_("")},
9765  /* 21 */ {0, {44,332,60,444}, CHECK, N_("Title Box")}
9766 };
9767 static DIALOG us_drawingoptdialog = {{50,75,239,609}, N_("Frame Options"), 0, 21, us_drawingoptdialogitems, 0, 0};
9768 
9769 /* special items for the "Drawing Options" dialog: */
9770 #define DFRO_FRAMESIZE      8		/* Frame size (popup) */
9771 #define DFRO_LANDSCAPE      9		/* Landscape (radio) */
9772 #define DFRO_PORTRAIT      10		/* Portrait (radio) */
9773 #define DFRO_CELLNAME      11		/* Cell name (stat text) */
9774 #define DFRO_COMPANYNAME   12		/* Company Name (edit text) */
9775 #define DFRO_DESIGNERNAME  14		/* Designer Name (edit text) */
9776 #define DFRO_PROJECTAME    15		/* Project name (edit text) */
9777 #define DFRO_LIBLIST       17		/* List of libraries (popup) */
9778 #define DFRO_LCOMPANYNAME  18		/* Company Name for library (edit text) */
9779 #define DFRO_LDESIGNERNAME 19		/* Designer Name for library (edit text) */
9780 #define DFRO_LPROJECTAME   20		/* Project name for library (edit text) */
9781 #define DFRO_TITLEBOX      21		/* Draw title box (check) */
9782 
us_frameoptionsdlog(void)9783 INTBIG us_frameoptionsdlog(void)
9784 {
9785 	INTBIG itemHit, i, newframesize, vertical, newvertical, total, title, newtitle,
9786 		curframesize, origframesize;
9787 	BOOLEAN redraw;
9788 	REGISTER VARIABLE *var;
9789 	REGISTER NODEPROTO *np;
9790 	REGISTER LIBRARY *lib, *curlib;
9791 	REGISTER WINDOWPART *w;
9792 	REGISTER CHAR *pt;
9793 	CHAR line[10], *newlang[7], **liblist, **threestrings;
9794 	static CHAR *framenames[] = {N_("None"), N_("Half-A-Size"), N_("A-Size"),
9795 		N_("B-Size"), N_("C-Size"), N_("D-Size"), N_("E-Size")};
9796 	REGISTER void *infstr, *dia;
9797 
9798 	/* show the frame options dialog */
9799 	dia = DiaInitDialog(&us_drawingoptdialog);
9800 	if (dia == 0) return(0);
9801 	liblist = us_makelibrarylist(&total, el_curlib, &i);
9802 	DiaSetPopup(dia, DFRO_LIBLIST, total, liblist);
9803 	if (i >= 0) DiaSetPopupEntry(dia, DFRO_LIBLIST, i);
9804 
9805 	/* defaults for all libraries */
9806 	var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_company_name"));
9807 	if (var != NOVARIABLE) DiaSetText(dia, DFRO_COMPANYNAME, (CHAR *)var->addr);
9808 	var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_designer_name"));
9809 	if (var != NOVARIABLE) DiaSetText(dia, DFRO_DESIGNERNAME, (CHAR *)var->addr);
9810 	var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_project_name"));
9811 	if (var != NOVARIABLE) DiaSetText(dia, DFRO_PROJECTAME, (CHAR *)var->addr);
9812 
9813 	/* for the current library */
9814 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
9815 	{
9816 		threestrings = (CHAR **)emalloc(3 * (sizeof (CHAR *)), us_tool->cluster);
9817 		if (threestrings == 0) return(0);
9818 		var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_company_name"));
9819 		if (var != NOVARIABLE) pt = (CHAR *)var->addr; else pt = x_("");
9820 		allocstring(&threestrings[0], pt, us_tool->cluster);
9821 		var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_designer_name"));
9822 		if (var != NOVARIABLE) pt = (CHAR *)var->addr; else pt = x_("");
9823 		allocstring(&threestrings[1], pt, us_tool->cluster);
9824 		var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_project_name"));
9825 		if (var != NOVARIABLE) pt = (CHAR *)var->addr; else pt = x_("");
9826 		allocstring(&threestrings[2], pt, us_tool->cluster);
9827 		lib->temp1 = (INTBIG)threestrings;
9828 	}
9829 	threestrings = (CHAR **)el_curlib->temp1;
9830 	DiaSetText(dia, DFRO_LCOMPANYNAME, threestrings[0]);
9831 	DiaSetText(dia, DFRO_LDESIGNERNAME, threestrings[1]);
9832 	DiaSetText(dia, DFRO_LPROJECTAME, threestrings[2]);
9833 	curlib = el_curlib;
9834 
9835 	np = getcurcell();
9836 	if (np != NONODEPROTO)
9837 	{
9838 		infstr = initinfstr();
9839 		addstringtoinfstr(infstr, _("For cell: "));
9840 		addstringtoinfstr(infstr, describenodeproto(np));
9841 		DiaSetText(dia, DFRO_CELLNAME, returninfstr(infstr));
9842 		for(i=0; i<7; i++) newlang[i] = TRANSLATE(framenames[i]);
9843 		DiaSetPopup(dia, DFRO_FRAMESIZE, 7, newlang);
9844 		DiaUnDimItem(dia, DFRO_LANDSCAPE);
9845 		DiaUnDimItem(dia, DFRO_PORTRAIT);
9846 		DiaUnDimItem(dia, DFRO_TITLEBOX);
9847 		curframesize = 0;
9848 		title = 0;
9849 		var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, el_schematic_page_size_key);
9850 		if (var != NOVARIABLE)
9851 		{
9852 			pt = (CHAR *)var->addr;
9853 			if (*pt == 'x') curframesize = 0; else
9854 			if (*pt == 'h') curframesize = 1; else
9855 			if (*pt == 'a') curframesize = 2; else
9856 			if (*pt == 'b') curframesize = 3; else
9857 			if (*pt == 'c') curframesize = 4; else
9858 			if (*pt == 'd') curframesize = 5; else
9859 			if (*pt == 'e') curframesize = 6; else curframesize = 5;
9860 			pt++;
9861 			DiaSetPopupEntry(dia, DFRO_FRAMESIZE, curframesize);
9862 			vertical = 0;
9863 			title = 1;
9864 			while (*pt != 0)
9865 			{
9866 				if (*pt == 'v') vertical = 1;
9867 				if (*pt == 'n') title = 0;
9868 				pt++;
9869 			}
9870 			if (curframesize > 0)
9871 			{
9872 				if (vertical != 0) DiaSetControl(dia, DFRO_PORTRAIT, 1); else
9873 					DiaSetControl(dia, DFRO_LANDSCAPE, 1);
9874 			}
9875 		}
9876 		if (title != 0) DiaSetControl(dia, DFRO_TITLEBOX, 1);
9877 		origframesize = curframesize;
9878 	} else
9879 	{
9880 		DiaSetText(dia, DFRO_CELLNAME, _("No cell in window"));
9881 		DiaDimItem(dia, DFRO_LANDSCAPE);
9882 		DiaDimItem(dia, DFRO_PORTRAIT);
9883 		DiaDimItem(dia, DFRO_TITLEBOX);
9884 	}
9885 	for(;;)
9886 	{
9887 		itemHit = DiaNextHit(dia);
9888 		if (itemHit == CANCEL || itemHit == OK) break;
9889 		if (itemHit == DFRO_FRAMESIZE)
9890 		{
9891 			i = DiaGetPopupEntry(dia, DFRO_FRAMESIZE);
9892 			if (i == 0)
9893 			{
9894 				DiaSetControl(dia, DFRO_LANDSCAPE, 0);
9895 				DiaSetControl(dia, DFRO_PORTRAIT, 0);
9896 			} else
9897 			{
9898 				if (DiaGetControl(dia, DFRO_LANDSCAPE) == 0 && DiaGetControl(dia, DFRO_PORTRAIT) == 0)
9899 					DiaSetControl(dia, DFRO_LANDSCAPE, 1);
9900 				if (curframesize == 0) DiaSetControl(dia, DFRO_TITLEBOX, 1);
9901 			}
9902 			curframesize = i;
9903 		}
9904 		if (itemHit == DFRO_TITLEBOX)
9905 		{
9906 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
9907 			continue;
9908 		}
9909 		if (itemHit == DFRO_LANDSCAPE || itemHit == DFRO_PORTRAIT)
9910 		{
9911 			DiaSetControl(dia, DFRO_LANDSCAPE, 0);
9912 			DiaSetControl(dia, DFRO_PORTRAIT, 0);
9913 			DiaSetControl(dia, itemHit, 1);
9914 			continue;
9915 		}
9916 		if (itemHit == DFRO_LCOMPANYNAME)
9917 		{
9918 			threestrings = (CHAR **)curlib->temp1;
9919 			pt = DiaGetText(dia, DFRO_LCOMPANYNAME);
9920 			reallocstring(&threestrings[0], pt, us_tool->cluster);
9921 			continue;
9922 		}
9923 		if (itemHit == DFRO_LDESIGNERNAME)
9924 		{
9925 			threestrings = (CHAR **)curlib->temp1;
9926 			pt = DiaGetText(dia, DFRO_LDESIGNERNAME);
9927 			reallocstring(&threestrings[1], pt, us_tool->cluster);
9928 			continue;
9929 		}
9930 		if (itemHit == DFRO_LPROJECTAME)
9931 		{
9932 			threestrings = (CHAR **)curlib->temp1;
9933 			pt = DiaGetText(dia, DFRO_LPROJECTAME);
9934 			reallocstring(&threestrings[2], pt, us_tool->cluster);
9935 			continue;
9936 		}
9937 		if (itemHit == DFRO_LIBLIST)
9938 		{
9939 			i = DiaGetPopupEntry(dia, DFRO_LIBLIST);
9940 			lib = getlibrary(liblist[i]);
9941 			if (lib == NOLIBRARY) continue;
9942 			curlib = lib;
9943 			threestrings = (CHAR **)curlib->temp1;
9944 			DiaSetText(dia, DFRO_LCOMPANYNAME, threestrings[0]);
9945 			DiaSetText(dia, DFRO_LDESIGNERNAME, threestrings[1]);
9946 			DiaSetText(dia, DFRO_LPROJECTAME, threestrings[2]);
9947 			continue;
9948 		}
9949 	}
9950 	if (itemHit == OK)
9951 	{
9952 		redraw = FALSE;
9953 		if (np != NONODEPROTO)
9954 		{
9955 			newframesize = DiaGetPopupEntry(dia, DFRO_FRAMESIZE);
9956 			newvertical = DiaGetControl(dia, DFRO_PORTRAIT);
9957 			newtitle = DiaGetControl(dia, DFRO_TITLEBOX);
9958 			if (newframesize != origframesize || newvertical != vertical || newtitle != title)
9959 			{
9960 				redraw = TRUE;
9961 				var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, el_schematic_page_size_key);
9962 				if (newframesize == 0 && newtitle == 0)
9963 				{
9964 					if (var != NOVARIABLE)
9965 						(void)delvalkey((INTBIG)np, VNODEPROTO, el_schematic_page_size_key);
9966 				} else
9967 				{
9968 					pt = line;
9969 					switch (newframesize)
9970 					{
9971 						case 0: *pt++ = 'x';   break;
9972 						case 1: *pt++ = 'h';   break;
9973 						case 2: *pt++ = 'a';   break;
9974 						case 3: *pt++ = 'b';   break;
9975 						case 4: *pt++ = 'c';   break;
9976 						case 5: *pt++ = 'd';   break;
9977 						case 6: *pt++ = 'e';   break;
9978 					}
9979 					if (newvertical != 0) *pt++ = 'v';
9980 					if (newtitle == 0) *pt++ = 'n';
9981 					*pt = 0;
9982 					if (var == NOVARIABLE || estrcmp(line, (CHAR *)var->addr) != 0)
9983 						(void)setvalkey((INTBIG)np, VNODEPROTO, el_schematic_page_size_key,
9984 							(INTBIG)line, VSTRING);
9985 				}
9986 			}
9987 		}
9988 
9989 		pt = DiaGetText(dia, DFRO_COMPANYNAME);
9990 		while (*pt == ' ' || *pt == '\t') pt++;
9991 		var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_company_name"));
9992 		if (*pt == 0)
9993 		{
9994 			/* remove company information */
9995 			if (var != NOVARIABLE)
9996 				(void)delval((INTBIG)us_tool, VTOOL, x_("USER_drawing_company_name"));
9997 		} else
9998 		{
9999 			if (var == NOVARIABLE || estrcmp(pt, (CHAR *)var->addr) != 0)
10000 				(void)setval((INTBIG)us_tool, VTOOL, x_("USER_drawing_company_name"), (INTBIG)pt, VSTRING);
10001 		}
10002 
10003 		pt = DiaGetText(dia, DFRO_DESIGNERNAME);
10004 		while (*pt == ' ' || *pt == '\t') pt++;
10005 		var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_designer_name"));
10006 		if (*pt == 0)
10007 		{
10008 			/* remove designer information */
10009 			if (var != NOVARIABLE)
10010 				(void)delval((INTBIG)us_tool, VTOOL, x_("USER_drawing_designer_name"));
10011 		} else
10012 		{
10013 			if (var == NOVARIABLE || estrcmp(pt, (CHAR *)var->addr) != 0)
10014 				(void)setval((INTBIG)us_tool, VTOOL, x_("USER_drawing_designer_name"), (INTBIG)pt, VSTRING);
10015 		}
10016 
10017 		pt = DiaGetText(dia, DFRO_PROJECTAME);
10018 		while (*pt == ' ' || *pt == '\t') pt++;
10019 		var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_drawing_project_name"));
10020 		if (*pt == 0)
10021 		{
10022 			/* remove designer information */
10023 			if (var != NOVARIABLE)
10024 				(void)delval((INTBIG)us_tool, VTOOL, x_("USER_drawing_project_name"));
10025 		} else
10026 		{
10027 			if (var == NOVARIABLE || estrcmp(pt, (CHAR *)var->addr) != 0)
10028 				(void)setval((INTBIG)us_tool, VTOOL, x_("USER_drawing_project_name"), (INTBIG)pt, VSTRING);
10029 		}
10030 
10031 		/* save library-specific information */
10032 		for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
10033 		{
10034 			threestrings = (CHAR **)lib->temp1;
10035 			var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_company_name"));
10036 			if (*threestrings[0] == 0)
10037 			{
10038 				/* remove company information */
10039 				if (var != NOVARIABLE)
10040 					(void)delval((INTBIG)lib, VLIBRARY, x_("USER_drawing_company_name"));
10041 			} else
10042 			{
10043 				if (var == NOVARIABLE || estrcmp(threestrings[0], (CHAR *)var->addr) != 0)
10044 					(void)setval((INTBIG)lib, VLIBRARY, x_("USER_drawing_company_name"), (INTBIG)threestrings[0], VSTRING);
10045 			}
10046 
10047 			var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_designer_name"));
10048 			if (*threestrings[1] == 0)
10049 			{
10050 				/* remove company information */
10051 				if (var != NOVARIABLE)
10052 					(void)delval((INTBIG)lib, VLIBRARY, x_("USER_drawing_designer_name"));
10053 			} else
10054 			{
10055 				if (var == NOVARIABLE || estrcmp(threestrings[1], (CHAR *)var->addr) != 0)
10056 					(void)setval((INTBIG)lib, VLIBRARY, x_("USER_drawing_designer_name"), (INTBIG)threestrings[1], VSTRING);
10057 			}
10058 
10059 			var = getval((INTBIG)lib, VLIBRARY, VSTRING, x_("USER_drawing_project_name"));
10060 			if (*threestrings[2] == 0)
10061 			{
10062 				/* remove company information */
10063 				if (var != NOVARIABLE)
10064 					(void)delval((INTBIG)lib, VLIBRARY, x_("USER_drawing_project_name"));
10065 			} else
10066 			{
10067 				if (var == NOVARIABLE || estrcmp(threestrings[2], (CHAR *)var->addr) != 0)
10068 					(void)setval((INTBIG)lib, VLIBRARY, x_("USER_drawing_project_name"), (INTBIG)threestrings[2], VSTRING);
10069 			}
10070 		}
10071 
10072 		/* redraw if needed */
10073 		if (redraw && np != NONODEPROTO)
10074 		{
10075 			for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
10076 			{
10077 				if ((w->state&WINDOWTYPE) != DISPWINDOW) continue;
10078 				if (w->curnodeproto != np) continue;
10079 				if (w->redisphandler != 0) (*w->redisphandler)(w);
10080 			}
10081 		}
10082 	}
10083 	DiaDoneDialog(dia);
10084 	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
10085 	{
10086 		threestrings = (CHAR **)lib->temp1;
10087 		efree((CHAR *)threestrings[0]);
10088 		efree((CHAR *)threestrings[1]);
10089 		efree((CHAR *)threestrings[2]);
10090 		efree((CHAR *)threestrings);
10091 	}
10092 	efree((CHAR *)liblist);
10093 	return(0);
10094 }
10095 
10096 /****************************** GENERAL OPTIONS DIALOG ******************************/
10097 
10098 /* User Interface: General Options */
10099 static DIALOGITEM us_genoptdialogitems[] =
10100 {
10101  /*  1 */ {0, {180,268,204,348}, BUTTON, N_("OK")},
10102  /*  2 */ {0, {180,152,204,232}, BUTTON, N_("Cancel")},
10103  /*  3 */ {0, {8,8,24,216}, CHECK, N_("Beep after long jobs")},
10104  /*  4 */ {0, {80,8,96,308}, CHECK, N_("Include date and version in output files")},
10105  /*  5 */ {0, {180,40,204,120}, BUTTON, N_("Advanced")},
10106  /*  6 */ {0, {128,8,144,308}, MESSAGE, N_("Maximum errors to report (0 for infinite):")},
10107  /*  7 */ {0, {128,312,144,372}, EDITTEXT, x_("")},
10108  /*  8 */ {0, {56,8,72,308}, CHECK, N_("Expandable dialogs default to fullsize")},
10109  /*  9 */ {0, {32,8,48,308}, CHECK, N_("Click sounds when arcs are created")},
10110  /* 10 */ {0, {152,8,168,252}, MESSAGE, N_("Prevent motion after selection for:")},
10111  /* 11 */ {0, {152,256,168,304}, EDITTEXT, x_("")},
10112  /* 12 */ {0, {152,308,168,384}, MESSAGE, N_("seconds")},
10113  /* 13 */ {0, {104,8,120,384}, CHECK, N_("Show file-selection dialog before writing netlists")}
10114 };
10115 static DIALOG us_genoptdialog = {{75,75,288,469}, N_("General Options"), 0, 13, us_genoptdialogitems, 0, 0};
10116 
10117 /* special items for the "General Options" dialog: */
10118 #define DGNO_BEEPAFTERLONG    3		/* Beep after long jobs (check) */
10119 #define DGNO_PUTDATEINOUTPUT  4		/* Put date in output files (check) */
10120 #define DGNO_ADVANCEDSTUFF    5		/* Handle advanced stuff (button) */
10121 #define DGNO_MAXERRORS        7		/* Maximum errors to report (edit text) */
10122 #define DGNO_FULLSIZEDIALOGS  8		/* Start expandable dialogs fullsize (check) */
10123 #define DGNO_OTHERSOUNDS      9		/* Play other sounds (check) */
10124 #define DGNO_MOTIONDELAY     11		/* Motion delay after selection (edit text) */
10125 #define DGNO_FILESELECTDIA   13		/* Show file-selection dialog when writing netlists (check) */
10126 
10127 /* User Interface: Advanced */
10128 static DIALOGITEM us_advdialogitems[] =
10129 {
10130  /*  1 */ {0, {8,8,24,268}, MESSAGE, N_("These are advanced commands")},
10131  /*  2 */ {0, {14,276,38,352}, BUTTON, N_("Cancel")},
10132  /*  3 */ {0, {152,188,176,348}, BUTTON, N_("Edit Dialogs")},
10133  /*  4 */ {0, {88,16,112,176}, BUTTON, N_("List Changed Options")},
10134  /*  5 */ {0, {184,188,208,348}, BUTTON, N_("Examine Memory Arena")},
10135  /*  6 */ {0, {184,16,208,176}, BUTTON, N_("Dump Name Space")},
10136  /*  7 */ {0, {152,16,176,176}, BUTTON, N_("Show R-Tree for Cell")},
10137  /*  8 */ {0, {88,188,112,348}, BUTTON, N_("Save Options as Text")},
10138  /*  9 */ {0, {120,16,144,176}, BUTTON, N_("Interactive Undo")},
10139  /* 10 */ {0, {120,188,144,348}, BUTTON, N_("Toggle Internal Errors")},
10140  /* 11 */ {0, {54,188,78,348}, BUTTON, N_("Edit Variables")},
10141  /* 12 */ {0, {28,8,44,268}, MESSAGE, N_("And should not normally be used")},
10142  /* 13 */ {0, {54,16,78,176}, BUTTON, N_("Language Translation")}
10143 };
10144 static DIALOG us_advdialog = {{75,75,292,432}, N_("Advanced Users Only"), 0, 13, us_advdialogitems, 0, 0};
10145 
10146 /* special items for the "Advanced" dialog: */
10147 #define DADV_DIAEDIT      3		/* Edit dialogs (button) */
10148 #define DADV_CHANGEDOPT   4		/* List changed options (button) */
10149 #define DADV_MEMARENA     5		/* Dump memory arena (button) */
10150 #define DADV_NAMESPACE    6		/* Dump name space (button) */
10151 #define DADV_RTREES       7		/* Dump R-tree for current cell (button) */
10152 #define DADV_SAVEOPT      8		/* Save options as readable dump (button) */
10153 #define DADV_UNDO         9		/* Interactive Undo (button) */
10154 #define DADV_INTERNAL    10		/* Toggle internal errors (button) */
10155 #define DADV_VARIABLES   11		/* Edit variables (button) */
10156 #define DADV_TRANSLATE   13		/* Translate (button) */
10157 
us_generaloptionsdlog(void)10158 INTBIG us_generaloptionsdlog(void)
10159 {
10160 	INTBIG itemHit, newoptions, maxerrors, i, motiondelay;
10161 	REGISTER VARIABLE *var;
10162 	CHAR *par[2], line[50];
10163 	REGISTER void *dia;
10164 
10165 	/* show the frame options dialog */
10166 	dia = DiaInitDialog(&us_genoptdialog);
10167 	if (dia == 0) return(0);
10168 	if ((us_useroptions&NODATEORVERSION) == 0) DiaSetControl(dia, DGNO_PUTDATEINOUTPUT, 1);
10169 	if ((us_useroptions&NOPROMPTBEFOREWRITE) == 0) DiaSetControl(dia, DGNO_FILESELECTDIA, 1);
10170 	if ((us_useroptions&BEEPAFTERLONGJOB) != 0) DiaSetControl(dia, DGNO_BEEPAFTERLONG, 1);
10171 	if ((us_useroptions&EXPANDEDDIALOGSDEF) != 0) DiaSetControl(dia, DGNO_FULLSIZEDIALOGS, 1);
10172 	if ((us_useroptions&NOEXTRASOUND) == 0) DiaSetControl(dia, DGNO_OTHERSOUNDS, 1);
10173 
10174 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_maximum_errors"));
10175 	if (var == NOVARIABLE) maxerrors = 0; else
10176 		maxerrors = var->addr;
10177 	esnprintf(line, 50, x_("%ld"), maxerrors);
10178 	DiaSetText(dia, DGNO_MAXERRORS, line);
10179 
10180 	var = getvalkey((INTBIG)us_tool, VTOOL, VFRACT, us_motiondelaykey);
10181 	if (var == NOVARIABLE) motiondelay = WHOLE/2; else
10182 		motiondelay = var->addr;
10183 	DiaSetText(dia, DGNO_MOTIONDELAY, frtoa(motiondelay));
10184 
10185 	for(;;)
10186 	{
10187 		itemHit = DiaNextHit(dia);
10188 		if (itemHit == CANCEL || itemHit == OK || itemHit == DGNO_ADVANCEDSTUFF) break;
10189 		if (itemHit == DGNO_PUTDATEINOUTPUT || itemHit == DGNO_BEEPAFTERLONG ||
10190 			itemHit == DGNO_FULLSIZEDIALOGS || itemHit == DGNO_OTHERSOUNDS ||
10191 			itemHit == DGNO_FILESELECTDIA)
10192 		{
10193 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
10194 			continue;
10195 		}
10196 	}
10197 	if (itemHit != CANCEL)
10198 	{
10199 		newoptions = us_useroptions & ~(NODATEORVERSION | BEEPAFTERLONGJOB |
10200 			EXPANDEDDIALOGSDEF | NOEXTRASOUND | NOPROMPTBEFOREWRITE);
10201 		if (DiaGetControl(dia, DGNO_PUTDATEINOUTPUT) == 0) newoptions |= NODATEORVERSION;
10202 		if (DiaGetControl(dia, DGNO_FILESELECTDIA) == 0) newoptions |= NOPROMPTBEFOREWRITE;
10203 		if (DiaGetControl(dia, DGNO_BEEPAFTERLONG) != 0) newoptions |= BEEPAFTERLONGJOB;
10204 		if (DiaGetControl(dia, DGNO_FULLSIZEDIALOGS) != 0) newoptions |= EXPANDEDDIALOGSDEF;
10205 		if (DiaGetControl(dia, DGNO_OTHERSOUNDS) == 0) newoptions |= NOEXTRASOUND;
10206 		if (newoptions != us_useroptions)
10207 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, newoptions, VINTEGER);
10208 		i = eatoi(DiaGetText(dia, DGNO_MAXERRORS));
10209 		if (i != maxerrors)
10210 		{
10211 			if (i == 0)
10212 			{
10213 				if (getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_maximum_errors")) != NOVARIABLE)
10214 					delval((INTBIG)us_tool, VTOOL, x_("USER_maximum_errors"));
10215 			} else
10216 			{
10217 				(void)setval((INTBIG)us_tool, VTOOL, x_("USER_maximum_errors"), i, VINTEGER);
10218 			}
10219 		}
10220 		i = atofr(DiaGetText(dia, DGNO_MOTIONDELAY));
10221 		if (i != motiondelay)
10222 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_motiondelaykey, i, VFRACT);
10223 	}
10224 	DiaDoneDialog(dia);
10225 
10226 	/* handle advanced dialog if requested */
10227 	if (itemHit == DGNO_ADVANCEDSTUFF)
10228 	{
10229 		dia = DiaInitDialog(&us_advdialog);
10230 		if (dia == 0) return(0);
10231 		for(;;)
10232 		{
10233 			itemHit = DiaNextHit(dia);
10234 			if (itemHit == CANCEL) break;
10235 			if (itemHit == DADV_DIAEDIT)
10236 			{
10237 				DiaDoneDialog(dia);
10238 				par[0] = x_("dialog-edit");
10239 				us_debug(1, par);
10240 				return(0);
10241 			}
10242 			if (itemHit == DADV_CHANGEDOPT)
10243 			{
10244 				par[0] = x_("options-changed");
10245 				us_debug(1, par);
10246 				break;
10247 			}
10248 			if (itemHit == DADV_MEMARENA)
10249 			{
10250 				par[0] = x_("arena");
10251 				us_debug(1, par);
10252 				break;
10253 			}
10254 			if (itemHit == DADV_NAMESPACE)
10255 			{
10256 				par[0] = x_("namespace");
10257 				us_debug(1, par);
10258 				break;
10259 			}
10260 			if (itemHit == DADV_RTREES)
10261 			{
10262 				par[0] = x_("rtree");
10263 				us_debug(1, par);
10264 				break;
10265 			}
10266 			if (itemHit == DADV_SAVEOPT)
10267 			{
10268 				DiaDoneDialog(dia);
10269 				par[0] = x_("examine-options");
10270 				us_debug(1, par);
10271 				return(0);
10272 			}
10273 			if (itemHit == DADV_UNDO)
10274 			{
10275 				DiaDoneDialog(dia);
10276 				par[0] = x_("undo");
10277 				us_debug(1, par);
10278 				return(0);
10279 			}
10280 			if (itemHit == DADV_INTERNAL)
10281 			{
10282 				par[0] = x_("internal-errors");
10283 				us_debug(1, par);
10284 				break;
10285 			}
10286 			if (itemHit == DADV_VARIABLES)
10287 			{
10288 				DiaDoneDialog(dia);
10289 				(void)us_variablesdlog();
10290 				return(0);
10291 			}
10292 			if (itemHit == DADV_TRANSLATE)
10293 			{
10294 				DiaDoneDialog(dia);
10295 				us_translationdlog();
10296 				return(0);
10297 			}
10298 		}
10299 		DiaDoneDialog(dia);
10300 	}
10301 	return(0);
10302 }
10303 
10304 /****************************** GET INFO DIALOGS ******************************/
10305 
10306 static void   us_getinfonode(NODEINST *ni, BOOLEAN canspecialize);
10307 static void   us_getinfoarc(ARCINST *ai);
10308 static void   us_getinfotext(HIGHLIGHT *high, BOOLEAN canspecialize);
10309 static void   us_getinfoexport(HIGHLIGHT *high);
10310 static void   us_getnodedisplaysize(NODEINST *ni, INTBIG *xsize, INTBIG *ysize);
10311 static void   us_getnodemodfromdisplayinfo(NODEINST *ni, INTBIG xs, INTBIG ys, INTBIG xc, INTBIG yc,
10312 				INTBIG r, INTBIG t, BOOLEAN positionchanged, INTBIG *dlx, INTBIG *dly, INTBIG *dhx,
10313 				INTBIG *dhy, INTBIG *drot, INTBIG *dtran, BOOLEAN xyrev);
10314 static void   us_listmanyhighlights(INTBIG len, HIGHLIGHT *manyhigh, INTBIG *whichone, INTBIG *oftotal, void *dia);
10315 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
10316 extern "C"
10317 {
10318 #endif
10319 	static int    us_highlightsascending(const void *e1, const void *e2);
10320 #if defined(__cplusplus) && !defined(ALLCPLUSPLUS)
10321 }
10322 #endif
10323 
10324 /* Multiple Object Info */
10325 static DIALOGITEM us_multigetinfodialogitems[] =
10326 {
10327  /*  1 */ {0, {368,124,392,204}, BUTTON, N_("OK")},
10328  /*  2 */ {0, {368,16,392,96}, BUTTON, N_("Cancel")},
10329  /*  3 */ {0, {20,4,360,304}, SCROLLMULTI, x_("")},
10330  /*  4 */ {0, {0,4,16,304}, MESSAGE, N_("0 Objects:")},
10331  /*  5 */ {0, {28,308,44,388}, MESSAGE, N_("X Position:")},
10332  /*  6 */ {0, {28,392,44,472}, EDITTEXT, x_("")},
10333  /*  7 */ {0, {68,308,84,388}, MESSAGE, N_("Y Position:")},
10334  /*  8 */ {0, {68,392,84,472}, EDITTEXT, x_("")},
10335  /*  9 */ {0, {108,308,124,388}, MESSAGE, N_("X Size:")},
10336  /* 10 */ {0, {108,392,124,472}, EDITTEXT, x_("")},
10337  /* 11 */ {0, {148,308,164,388}, MESSAGE, N_("Y Size:")},
10338  /* 12 */ {0, {148,392,164,472}, EDITTEXT, x_("")},
10339  /* 13 */ {0, {220,308,236,388}, MESSAGE, N_("Width:")},
10340  /* 14 */ {0, {220,392,236,472}, EDITTEXT, x_("")},
10341  /* 15 */ {0, {8,308,24,472}, MESSAGE, N_("For all selected nodes:")},
10342  /* 16 */ {0, {200,308,216,472}, MESSAGE, N_("For all selected arcs:")},
10343  /* 17 */ {0, {368,232,392,312}, BUTTON, N_("Info")},
10344  /* 18 */ {0, {368,340,392,420}, BUTTON, N_("Remove")},
10345  /* 19 */ {0, {344,308,360,472}, POPUP, x_("")},
10346  /* 20 */ {0, {48,336,64,472}, MESSAGE, x_("")},
10347  /* 21 */ {0, {88,336,104,472}, MESSAGE, x_("")},
10348  /* 22 */ {0, {128,336,144,472}, MESSAGE, x_("")},
10349  /* 23 */ {0, {168,336,184,472}, MESSAGE, x_("")},
10350  /* 24 */ {0, {240,336,256,472}, MESSAGE, x_("")},
10351  /* 25 */ {0, {192,308,193,472}, DIVIDELINE, x_("")},
10352  /* 26 */ {0, {272,308,288,472}, MESSAGE, N_("For all selected exports:")},
10353  /* 27 */ {0, {264,308,265,472}, DIVIDELINE, x_("")},
10354  /* 28 */ {0, {292,308,308,472}, POPUP, x_("")},
10355  /* 29 */ {0, {316,308,317,472}, DIVIDELINE, x_("")},
10356  /* 30 */ {0, {324,308,340,472}, MESSAGE, N_("For everything:")}
10357 };
10358 static DIALOG us_multigetinfodialog = {{75,75,476,556}, N_("Multiple Object Information"), 0, 30, us_multigetinfodialogitems, 0, 0};
10359 
10360 /* special items for the "Multiple-object Get Info" dialog: */
10361 #define DGIM_OBJECTLIST   3		/* list of objects (scroll) */
10362 #define DGIM_OBJECTCOUNT  4		/* object count (stat text) */
10363 #define DGIM_NODEXPOS     6		/* node X position (edit text) */
10364 #define DGIM_NODEYPOS     8		/* node Y position (edit text) */
10365 #define DGIM_NODEXSIZE   10		/* node X size (edit text) */
10366 #define DGIM_NODEYSIZE   12		/* node Y size (edit text) */
10367 #define DGIM_ARCWIDTH    14		/* arc width (edit text) */
10368 #define DGIM_INFO        17		/* info (button) */
10369 #define DGIM_REMOVE      18		/* remove (button) */
10370 #define DGIM_SELECTION   19		/* selection (popup) */
10371 #define DGIM_NODEXPRANGE 20		/* range of node X position values (stat text) */
10372 #define DGIM_NODEYPRANGE 21		/* range of node Y position values (stat text) */
10373 #define DGIM_NODEXSRANGE 22		/* range of node X size values (stat text) */
10374 #define DGIM_NODEYSRANGE 23		/* range of node Y size values (stat text) */
10375 #define DGIM_ARCWIDRANGE 24		/* range of arc width values (stat text) */
10376 #define DGIM_EXPORTCHARS 28		/* characteristics of all exports (popup) */
10377 
us_showdlog(BOOLEAN canspecialize)10378 INTBIG us_showdlog(BOOLEAN canspecialize)
10379 {
10380 	HIGHLIGHT high, *manyhigh;
10381 	CHAR *pt, *newlang[NUMPORTCHARS+1];
10382 	REGISTER NODEINST *ni, *ni1, *ni2, **nis, *onenode;
10383 	REGISTER ARCINST *ai, *onearc;
10384 	REGISTER GEOM *geom, *got1, *got2;
10385 	REGISTER BOOLEAN nodeinfochanged, arcinfochanged, positionchanged, xyrev, highlightchanged;
10386 	REGISTER INTBIG len, i, j, k, swap, distx, disty, cx, cy, gotjustone, *linelist,
10387 		nodistx, nodisty, value, *whichone, *oftotal, *dlxs, *dlys, *dhxs, *dhys,
10388 		*drots, *dtrans, newbit, lambda;
10389 	INTBIG lx1, hx1, ly1, hy1, lx2, hx2, ly2, hy2,
10390 		xpos, ypos, xsize, ysize, cx1, cy1, cx2, cy2;
10391 	XARRAY trans;
10392 	REGISTER INTBIG itemHit, which;
10393 	REGISTER VARIABLE *var;
10394 	REGISTER void *infstr;
10395 	REGISTER void *dia;
10396 
10397 	/* if in outline-edit mode, show the points */
10398 	if ((el_curwindowpart->state&WINDOWOUTLINEEDMODE) != 0)
10399 	{
10400 		us_tracedlog();
10401 		return(0);
10402 	}
10403 
10404 	/* see if anything is highlighted */
10405 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
10406 	if (var == NOVARIABLE)
10407 	{
10408 		us_abortcommand(_("Nothing is highlighted"));
10409 		return(0);
10410 	}
10411 
10412 	/* special dialog when only 1 highlighted object */
10413 	gotjustone = -1;
10414 	onenode = NONODEINST;
10415 	onearc = NOARCINST;
10416 	len = getlength(var);
10417 	for(i=0; i<len; i++)
10418 	{
10419 		if (us_makehighlight(((CHAR **)var->addr)[i], &high)) continue;
10420 		if ((high.status&HIGHTYPE) != HIGHFROM) continue;
10421 		if (high.fromgeom == NOGEOM)
10422 		{
10423 			gotjustone = -1;
10424 			break;
10425 		}
10426 		gotjustone = i;
10427 		if (!high.fromgeom->entryisnode)
10428 		{
10429 			ai = high.fromgeom->entryaddr.ai;
10430 			if (onearc == NOARCINST) onearc = ai;
10431 			if (onearc == ai) continue;
10432 			gotjustone = -1;
10433 			break;
10434 		} else
10435 		{
10436 			ni = high.fromgeom->entryaddr.ni;
10437 			if (onenode == NONODEINST) onenode = ni;
10438 			if (onenode == ni) continue;
10439 			gotjustone = -1;
10440 			break;
10441 		}
10442 	}
10443 	if (onenode != NONODEINST && onearc != NOARCINST) gotjustone = -1;
10444 	if (len == 1) gotjustone = 0;
10445 	if (gotjustone >= 0)
10446 	{
10447 		/* get the one highlighted object */
10448 		if (us_makehighlight(((CHAR **)var->addr)[gotjustone], &high))
10449 		{
10450 			us_abortcommand(_("Highlight unintelligible"));
10451 			return(0);
10452 		}
10453 
10454 		if ((high.status&HIGHTYPE) == HIGHTEXT)
10455 		{
10456 			if (high.fromvar == NOVARIABLE && high.fromport != NOPORTPROTO)
10457 				us_getinfoexport(&high); else
10458 					us_getinfotext(&high, canspecialize);
10459 			return(0);
10460 		}
10461 		if ((high.status&HIGHTYPE) == HIGHFROM)
10462 		{
10463 			if (!high.fromgeom->entryisnode)
10464 			{
10465 				/* arc getinfo */
10466 				ai = (ARCINST *)high.fromgeom->entryaddr.ai;
10467 				us_getinfoarc(ai);
10468 				return(0);
10469 			}
10470 			ni = (NODEINST *)high.fromgeom->entryaddr.ni;
10471 			us_getinfonode(ni, canspecialize);
10472 			return(0);
10473 		}
10474 	}
10475 
10476 	/* multiple objects highlighted: remember them all */
10477 	manyhigh = (HIGHLIGHT *)emalloc(len * (sizeof (HIGHLIGHT)), el_tempcluster);
10478 	if (manyhigh == 0) return(0);
10479 	whichone = (INTBIG *)emalloc(len * SIZEOFINTBIG, el_tempcluster);
10480 	if (whichone == 0) return(0);
10481 	oftotal = (INTBIG *)emalloc(len * SIZEOFINTBIG, el_tempcluster);
10482 	if (oftotal == 0) return(0);
10483 	for(i=0; i<len; i++)
10484 	{
10485 		if (us_makehighlight(((CHAR **)var->addr)[i], &manyhigh[i]))
10486 		{
10487 			us_abortcommand(_("Highlight unintelligible"));
10488 			break;
10489 		}
10490 	}
10491 
10492 	/* sort the objects */
10493 	esort(manyhigh, len, sizeof (HIGHLIGHT), us_highlightsascending);
10494 
10495 	/* determine the enumeration of repeats */
10496 	for(i=0; i<len; i++)
10497 	{
10498 		whichone[i] = oftotal[i] = 0;
10499 		for(j=i+1; j<len; j++)
10500 		{
10501 			if ((manyhigh[i].status&HIGHTYPE) != (manyhigh[j].status&HIGHTYPE))
10502 				break;
10503 			if ((manyhigh[i].status&HIGHTYPE) == HIGHFROM)
10504 			{
10505 				got1 = manyhigh[i].fromgeom;
10506 				got2 = manyhigh[j].fromgeom;
10507 				if (got1->entryisnode != got2->entryisnode) break;
10508 				if (got1->entryisnode)
10509 				{
10510 					if (got1->entryaddr.ni->proto != got2->entryaddr.ni->proto) break;
10511 				} else
10512 				{
10513 					if (got1->entryaddr.ai->proto != got2->entryaddr.ai->proto) break;
10514 				}
10515 			}
10516 		}
10517 		if (j == i+1) continue;
10518 		for(k=i; k<j; k++)
10519 		{
10520 			whichone[k] = k-i+1;
10521 			oftotal[k] = j-i;
10522 		}
10523 		i = j-1;
10524 	}
10525 
10526 	dia = DiaInitDialog(&us_multigetinfodialog);
10527 	if (dia == 0)
10528 	{
10529 		efree((CHAR *)manyhigh);
10530 		efree((CHAR *)whichone);
10531 		efree((CHAR *)oftotal);
10532 		return(0);
10533 	}
10534 	DiaInitTextDialog(dia, DGIM_OBJECTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
10535 		SCSELMOUSE|SCDOUBLEQUIT|SCREPORT);
10536 	newlang[0] = _("Leave selection alone");
10537 	newlang[1] = _("Make all Hard-to-select");
10538 	newlang[2] = _("Make all Easy-to-select");
10539 	DiaSetPopup(dia, DGIM_SELECTION, 3, newlang);
10540 
10541 	newlang[0] = _("Leave selection alone");
10542 	for(i=0; i<NUMPORTCHARS; i++) newlang[i+1] = TRANSLATE(us_exportcharnames[i]);
10543 	DiaSetPopup(dia, DGIM_EXPORTCHARS, NUMPORTCHARS, newlang);
10544 
10545 	/* multiple objects selected: list them */
10546 	us_listmanyhighlights(len, manyhigh, whichone, oftotal, dia);
10547 
10548 	/* if there are exactly two node/arc objects, show the distance between them */
10549 	got1 = got2 = NOGEOM;
10550 	for(i=0; i<len; i++)
10551 	{
10552 		if ((manyhigh[i].status&HIGHTYPE) == HIGHFROM)
10553 		{
10554 			geom = manyhigh[i].fromgeom;
10555 			cx = (geom->lowx + geom->highx) / 2;
10556 			cy = (geom->lowy + geom->highy) / 2;
10557 			if (i == 0)
10558 			{
10559 				got1 = geom;
10560 				cx1 = cx;
10561 				cy1 = cy;
10562 			} else if (i == 1)
10563 			{
10564 				got2 = geom;
10565 				cx2 = cx;
10566 				cy2 = cy;
10567 			}
10568 		}
10569 	}
10570 	if (len == 2 && got1 != NOGEOM && got2 != NOGEOM)
10571 	{
10572 		DiaStuffLine(dia, DGIM_OBJECTLIST, x_("----------------------------"));
10573 		infstr = initinfstr();
10574 		if (got1->entryisnode)
10575 			us_getnodedisplayposition(got1->entryaddr.ni, &cx1, &cy1);
10576 		if (got2->entryisnode)
10577 			us_getnodedisplayposition(got2->entryaddr.ni, &cx2, &cy2);
10578 		formatinfstr(infstr, _("Distance between objects: X=%s Y=%s"),
10579 			latoa(abs(cx1-cx2), 0), latoa(abs(cy1-cy2), 0));
10580 		DiaStuffLine(dia, DGIM_OBJECTLIST, returninfstr(infstr));
10581 		if (got1->entryisnode && got1->entryaddr.ni->proto->primindex == 0 &&
10582 			got2->entryisnode && got2->entryaddr.ni->proto->primindex == 0)
10583 		{
10584 			/* report edge distance between two cell instances */
10585 			ni1 = got1->entryaddr.ni;
10586 			lx1 = ni1->lowx;   hx1 = ni1->highx;
10587 			ly1 = ni1->lowy;   hy1 = ni1->highy;
10588 			makerot(ni1, trans);
10589 			xform(lx1, ly1, &lx1, &ly1, trans);
10590 			xform(hx1, hy1, &hx1, &hy1, trans);
10591 			if (hx1 < lx1) { swap = lx1;   lx1 = hx1;   hx1 = swap; }
10592 			if (hy1 < ly1) { swap = ly1;   ly1 = hy1;   hy1 = swap; }
10593 
10594 			ni2 = got2->entryaddr.ni;
10595 			lx2 = ni2->lowx;   hx2 = ni2->highx;
10596 			ly2 = ni2->lowy;   hy2 = ni2->highy;
10597 			makerot(ni2, trans);
10598 			xform(lx2, ly2, &lx2, &ly2, trans);
10599 			xform(hx2, hy2, &hx2, &hy2, trans);
10600 			if (hx2 < lx2) { swap = lx2;   lx2 = hx2;   hx2 = swap; }
10601 			if (hy2 < ly2) { swap = ly2;   ly2 = hy2;   hy2 = swap; }
10602 
10603 			nodistx = nodisty = 0;
10604 			if (lx1 > hx2) distx = lx1 - hx2; else
10605 			{
10606 				if (lx2 > hx1) distx = lx2 - hx1; else
10607 				{
10608 					nodistx = 1;
10609 					distx = 0;
10610 				}
10611 			}
10612 			if (ly1 > hy2) disty = ly1 - hy2; else
10613 			{
10614 				if (ly2 > hy1) disty = ly2 - hy1; else
10615 				{
10616 					nodisty = 1;
10617 					disty = 0;
10618 				}
10619 			}
10620 			if (nodistx != 0 && nodisty != 0)
10621 				DiaStuffLine(dia, DGIM_OBJECTLIST, _("Cells overlap")); else
10622 			{
10623 				infstr = initinfstr();
10624 				addstringtoinfstr(infstr, _("Distance between edges:"));
10625 				if (nodistx == 0)
10626 				{
10627 					formatinfstr(infstr, _(" X=%s"), latoa(distx, 0));
10628 				}
10629 				if (nodisty == 0)
10630 				{
10631 					formatinfstr(infstr, _(" Y=%s"), latoa(disty, 0));
10632 				}
10633 				DiaStuffLine(dia, DGIM_OBJECTLIST, returninfstr(infstr));
10634 			}
10635 		}
10636 	}
10637 
10638 	/* loop dialog */
10639 	highlightchanged = nodeinfochanged = arcinfochanged = positionchanged = FALSE;
10640 	for(;;)
10641 	{
10642 		itemHit = DiaNextHit(dia);
10643 		if (itemHit == OK || itemHit == CANCEL || itemHit == DGIM_INFO) break;
10644 		if (itemHit == DGIM_OBJECTLIST)
10645 		{
10646 			linelist = DiaGetCurLines(dia, DGIM_OBJECTLIST);
10647 			us_clearhighlightcount();
10648 			highlightchanged = TRUE;
10649 			j = 0;
10650 			for(i=0; linelist[i] >= 0; i++)
10651 			{
10652 				which = linelist[i];
10653 				if (which >= len) continue;
10654 				high = manyhigh[which];
10655 				us_addhighlight(&high);
10656 				j++;
10657 			}
10658 			if (j == 0)
10659 			{
10660 				DiaDimItem(dia, DGIM_INFO);
10661 				DiaDimItem(dia, DGIM_REMOVE);
10662 			} else
10663 			{
10664 				DiaUnDimItem(dia, DGIM_INFO);
10665 				DiaUnDimItem(dia, DGIM_REMOVE);
10666 			}
10667 			us_showallhighlight();
10668 			us_endchanges(NOWINDOWPART);
10669 			continue;
10670 		}
10671 		if (itemHit == DGIM_NODEXPOS || itemHit == DGIM_NODEYPOS ||
10672 			itemHit == DGIM_NODEXSIZE || itemHit == DGIM_NODEYSIZE)
10673 		{
10674 			nodeinfochanged = TRUE;
10675 			if (itemHit == DGIM_NODEXPOS || itemHit == DGIM_NODEYPOS) positionchanged = TRUE;
10676 			continue;
10677 		}
10678 		if (itemHit == DGIM_ARCWIDTH)
10679 		{
10680 			arcinfochanged = TRUE;
10681 			continue;
10682 		}
10683 		if (itemHit == DGIM_REMOVE)
10684 		{
10685 			linelist = DiaGetCurLines(dia, DGIM_OBJECTLIST);
10686 			j = 0;
10687 			for(i=0; linelist[i] >= 0; i++) j++;
10688 			esort(linelist, j, SIZEOFINTBIG, sort_intbigdescending);
10689 			which = len;
10690 			for(i=0; i<j; i++)
10691 			{
10692 				which = linelist[i];
10693 				if (which >= len) continue;
10694 				for(k=which; k<len-1; k++)
10695 				{
10696 					manyhigh[k] = manyhigh[k+1];
10697 					whichone[k] = whichone[k+1];
10698 					oftotal[k] = oftotal[k+1];
10699 				}
10700 				len--;
10701 			}
10702 			while (which >= len && which > 0) which--;
10703 			if (which < len)
10704 			{
10705 				high = manyhigh[which];
10706 				us_clearhighlightcount();
10707 				us_addhighlight(&high);
10708 				us_showallhighlight();
10709 				us_endchanges(NOWINDOWPART);
10710 			}
10711 			highlightchanged = TRUE;
10712 			us_listmanyhighlights(len, manyhigh, whichone, oftotal, dia);
10713 			continue;
10714 		}
10715 	}
10716 
10717 	/* remember the selected item */
10718 	which = DiaGetCurLine(dia, DGIM_OBJECTLIST);
10719 
10720 	/* if cancelling, restore highlighting */
10721 	if (itemHit == CANCEL && highlightchanged)
10722 	{
10723 		us_clearhighlightcount();
10724 		for(i=0; i<len; i++)
10725 			us_addhighlight(&manyhigh[i]);
10726 	}
10727 
10728 	/* accept multiple changes */
10729 	if (itemHit != CANCEL && (arcinfochanged || nodeinfochanged ||
10730 		DiaGetPopupEntry(dia, DGIM_SELECTION) != 0 || DiaGetPopupEntry(dia, DGIM_EXPORTCHARS) != 0))
10731 	{
10732 		us_pushhighlight();
10733 		us_clearhighlightcount();
10734 		if (nodeinfochanged)
10735 		{
10736 			/* handle multiple changes at once */
10737 			nis = (NODEINST **)emalloc(len * (sizeof (NODEINST *)), us_tool->cluster);
10738 			dlxs = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10739 			dlys = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10740 			dhxs = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10741 			dhys = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10742 			drots = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10743 			dtrans = (INTBIG *)emalloc(len * SIZEOFINTBIG, us_tool->cluster);
10744 			k = 0;
10745 			for(i=0; i<len; i++)
10746 			{
10747 				high = manyhigh[i];
10748 				if ((high.status&HIGHTYPE) != HIGHFROM) continue;
10749 				if (!high.fromgeom->entryisnode) continue;
10750 				ni = (NODEINST *)high.fromgeom->entryaddr.ni;
10751 				us_getnodedisplaysize(ni, &xsize, &ysize);
10752 				xyrev = FALSE;
10753 				if (ni->transpose == 0)
10754 				{
10755 					if (ni->rotation == 900 || ni->rotation == 2700) xyrev = TRUE;
10756 				} else
10757 				{
10758 					if (ni->rotation == 0 || ni->rotation == 1800) xyrev = TRUE;
10759 				}
10760 				us_getnodedisplayposition(ni, &xpos, &ypos);
10761 				pt = DiaGetText(dia, DGIM_NODEXPOS);
10762 				if (*pt != 0) xpos = atola(pt, 0);
10763 				pt = DiaGetText(dia, DGIM_NODEYPOS);
10764 				if (*pt != 0) ypos = atola(pt, 0);
10765 				if (ni->proto->primindex != 0)
10766 				{
10767 					pt = DiaGetText(dia, DGIM_NODEXSIZE);
10768 					if (*pt != 0) xsize = atola(pt, 0);
10769 					pt = DiaGetText(dia, DGIM_NODEYSIZE);
10770 					if (*pt != 0) ysize = atola(pt, 0);
10771 				}
10772 				us_getnodemodfromdisplayinfo(ni, xsize, ysize, xpos, ypos,
10773 					ni->rotation, ni->transpose, positionchanged, &dlxs[k], &dlys[k], &dhxs[k], &dhys[k],
10774 						&drots[k], &dtrans[k], xyrev);
10775 				nis[k] = ni;
10776 				k++;
10777 			}
10778 			for(i=0; i<k; i++)
10779 				startobjectchange((INTBIG)nis[i], VNODEINST);
10780 			modifynodeinsts(k, nis, dlxs, dlys, dhxs, dhys, drots, dtrans);
10781 			for(i=0; i<k; i++)
10782 				endobjectchange((INTBIG)nis[i], VNODEINST);
10783 			efree((CHAR *)nis);
10784 			efree((CHAR *)dlxs);
10785 			efree((CHAR *)dlys);
10786 			efree((CHAR *)dhxs);
10787 			efree((CHAR *)dhys);
10788 			efree((CHAR *)drots);
10789 			efree((CHAR *)dtrans);
10790 		}
10791 		if (arcinfochanged)
10792 		{
10793 			for(i=0; i<len; i++)
10794 			{
10795 				high = manyhigh[i];
10796 				if ((high.status&HIGHTYPE) != HIGHFROM) continue;
10797 				if (high.fromgeom->entryisnode) continue;
10798 				ai = (ARCINST *)high.fromgeom->entryaddr.ai;
10799 				lambda = lambdaofarc(ai);
10800 				value = atola(DiaGetText(dia, DGIM_ARCWIDTH), lambda);
10801 				if (value >= 0)
10802 				{
10803 					value = arcwidthoffset(ai) + value;
10804 					if (value != ai->width)
10805 					{
10806 						startobjectchange((INTBIG)ai, VARCINST);
10807 						(void)modifyarcinst(ai, value - ai->width, 0, 0, 0, 0);
10808 						endobjectchange((INTBIG)ai, VARCINST);
10809 					}
10810 				}
10811 			}
10812 		}
10813 
10814 		/* if export characteristics changed */
10815 		j = DiaGetPopupEntry(dia, DGIM_EXPORTCHARS);
10816 		if (j != 0)
10817 		{
10818 			for(i=0; i<len; i++)
10819 			{
10820 				high = manyhigh[i];
10821 				if ((high.status&HIGHTYPE) != HIGHTEXT) continue;
10822 				if (high.fromgeom == NOGEOM) continue;
10823 				if (high.fromport == NOPORTPROTO) continue;
10824 				newbit = high.fromport->userbits;
10825 				newbit = (newbit & ~STATEBITS) | us_exportcharlist[j-1];
10826 				if (newbit != (INTBIG)high.fromport->userbits)
10827 				{
10828 					setval((INTBIG)high.fromport, VPORTPROTO, x_("userbits"), newbit,
10829 						VINTEGER);
10830 					changeallports(high.fromport);
10831 				}
10832 			}
10833 		}
10834 
10835 		/* if selection changed, fix it */
10836 		j = DiaGetPopupEntry(dia, DGIM_SELECTION);
10837 		if (j != 0)
10838 		{
10839 			for(i=0; i<len; i++)
10840 			{
10841 				high = manyhigh[i];
10842 				if ((high.status&HIGHTYPE) != HIGHFROM) continue;
10843 				if (high.fromgeom->entryisnode)
10844 				{
10845 					ni = (NODEINST *)high.fromgeom->entryaddr.ni;
10846 					if (j == 1) ni->userbits |= HARDSELECTN; else
10847 						ni->userbits &= ~HARDSELECTN;
10848 				} else
10849 				{
10850 					ai = (ARCINST *)high.fromgeom->entryaddr.ai;
10851 					if (j == 1) ai->userbits |= HARDSELECTA; else
10852 						ai->userbits &= ~HARDSELECTA;
10853 				}
10854 			}
10855 		}
10856 		us_pophighlight(TRUE);
10857 	}
10858 	if (itemHit == DGIM_INFO) high = manyhigh[which];
10859 
10860 	/* cleanup */
10861 	DiaDoneDialog(dia);
10862 	efree((CHAR *)manyhigh);
10863 	efree((CHAR *)whichone);
10864 	efree((CHAR *)oftotal);
10865 
10866 	/* if info requested for one of the objects, give it now */
10867 	if (itemHit == DGIM_INFO)
10868 	{
10869 		if ((high.status&HIGHTYPE) == HIGHTEXT)
10870 		{
10871 			if (high.fromvar == NOVARIABLE && high.fromport != NOPORTPROTO)
10872 				us_getinfoexport(&high); else
10873 					us_getinfotext(&high, canspecialize);
10874 			return(0);
10875 		}
10876 		if ((high.status&HIGHTYPE) == HIGHFROM)
10877 		{
10878 			if (!high.fromgeom->entryisnode)
10879 			{
10880 				/* arc getinfo */
10881 				ai = (ARCINST *)high.fromgeom->entryaddr.ai;
10882 				us_getinfoarc(ai);
10883 				return(0);
10884 			}
10885 			ni = (NODEINST *)high.fromgeom->entryaddr.ni;
10886 			us_getinfonode(ni, canspecialize);
10887 			return(0);
10888 		}
10889 	}
10890 	return(0);
10891 }
10892 
10893 /*
10894  * Helper routine for "esort" that makes highlights go in ascending order
10895  * (used by "us_showdlog()").
10896  */
us_highlightsascending(const void * e1,const void * e2)10897 int us_highlightsascending(const void *e1, const void *e2)
10898 {
10899 	REGISTER HIGHLIGHT *c1, *c2;
10900 	REGISTER GEOM *got1, *got2;
10901 	REGISTER INTBIG s1, s2;
10902 	REGISTER INTBIG in1, in2;
10903 
10904 	c1 = (HIGHLIGHT *)e1;
10905 	c2 = (HIGHLIGHT *)e2;
10906 	s1 = c1->status & HIGHTYPE;
10907 	s2 = c2->status & HIGHTYPE;
10908 	if (s1 != s2) return(s1-s2);
10909 	if (s2 != HIGHFROM) return(0);
10910 	got1 = c1->fromgeom;
10911 	got2 = c2->fromgeom;
10912 	in1 = got1->entryisnode;
10913 	in2 = got2->entryisnode;
10914 	if (in1 != in2) return(in1-in2);
10915 	if (got1->entryisnode)
10916 	{
10917 		return(namesame(describenodeproto(got1->entryaddr.ni->proto),
10918 			describenodeproto(got2->entryaddr.ni->proto)));
10919 	}
10920 	return(namesame(got1->entryaddr.ai->proto->protoname,
10921 		got2->entryaddr.ai->proto->protoname));
10922 }
10923 
us_listmanyhighlights(INTBIG len,HIGHLIGHT * manyhigh,INTBIG * whichone,INTBIG * oftotal,void * dia)10924 void us_listmanyhighlights(INTBIG len, HIGHLIGHT *manyhigh, INTBIG *whichone, INTBIG *oftotal, void *dia)
10925 {
10926 	REGISTER INTBIG i, dx, dy, xsize, ysize, xpos, ypos, width, value, minxsize, maxxsize,
10927 		minysize, maxysize, minxpos, maxxpos, minypos, maxypos, minwidth, maxwidth;
10928 	INTBIG cx, cy, xvalue, yvalue;
10929 	XARRAY trans;
10930 	CHAR buf[100];
10931 	REGISTER NODEINST *ni;
10932 	REGISTER ARCINST *ai;
10933 	REGISTER GEOM *geom;
10934 	REGISTER VARIABLE *var;
10935 	REGISTER INTBIG gotxpos, gotypos, gotxsize, gotysize, gotwidth;
10936 	REGISTER void *infstr;
10937 
10938 	esnprintf(buf, 100, x_("%ld %s:"), len, makeplural(_("selection"), len));
10939 	DiaSetText(dia, DGIM_OBJECTCOUNT, buf);
10940 	gotxpos = gotypos = gotxsize = gotysize = gotwidth = xsize = ysize = xpos = ypos = width = 0;
10941 	DiaLoadTextDialog(dia, DGIM_OBJECTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
10942 	minxsize = minysize = minxpos = minypos = minwidth = 0;
10943 	maxxsize = maxysize = maxxpos = maxypos = maxwidth = -1;
10944 	for(i=0; i<len; i++)
10945 	{
10946 		infstr = initinfstr();
10947 		switch (manyhigh[i].status&HIGHTYPE)
10948 		{
10949 			case HIGHFROM:
10950 				geom = manyhigh[i].fromgeom;
10951 				cx = (geom->lowx + geom->highx) / 2;
10952 				cy = (geom->lowy + geom->highy) / 2;
10953 				if (geom->entryisnode)
10954 				{
10955 					ni = (NODEINST *)geom->entryaddr.ni;
10956 					addstringtoinfstr(infstr, _("Node "));
10957 					addstringtoinfstr(infstr, describenodeinst(ni));
10958 					var = getvalkey((INTBIG)ni->proto, VNODEPROTO, VINTEGER|VISARRAY,
10959 						el_prototype_center_key);
10960 					if (var != NOVARIABLE)
10961 					{
10962 						dx = ((INTBIG *)var->addr)[0] + (ni->lowx+ni->highx)/2 -
10963 							(ni->proto->lowx+ni->proto->highx)/2;
10964 						dy = ((INTBIG *)var->addr)[1] + (ni->lowy+ni->highy)/2 -
10965 							(ni->proto->lowy+ni->proto->highy)/2;
10966 						makerot(ni, trans);
10967 						xform(dx, dy, &cx, &cy, trans);
10968 					}
10969 
10970 					/* accumulate X and Y size */
10971 					if (ni->proto->primindex != 0)
10972 					{
10973 						us_getnodedisplaysize(ni, &xvalue, &yvalue);
10974 						if (minxsize > maxxsize) minxsize = maxxsize = xvalue; else
10975 						{
10976 							if (xvalue < minxsize) minxsize = xvalue;
10977 							if (xvalue > maxxsize) maxxsize = xvalue;
10978 						}
10979 						if (minysize > maxysize) minysize = maxysize = yvalue; else
10980 						{
10981 							if (yvalue < minysize) minysize = yvalue;
10982 							if (yvalue > maxysize) maxysize = yvalue;
10983 						}
10984 						if (gotxsize == 0)
10985 						{
10986 							xsize = xvalue;
10987 							gotxsize = 1;
10988 						} else if (gotxsize == 1)
10989 						{
10990 							if (xsize != xvalue) gotxsize = -1;
10991 						}
10992 						if (gotysize == 0)
10993 						{
10994 							ysize = yvalue;
10995 							gotysize = 1;
10996 						} else if (gotysize == 1)
10997 						{
10998 							if (ysize != yvalue) gotysize = -1;
10999 						}
11000 					}
11001 
11002 					/* accumulate X and Y position */
11003 					us_getnodedisplayposition(ni, &xvalue, &yvalue);
11004 					if (minxpos > maxxpos) minxpos = maxxpos = xvalue; else
11005 					{
11006 						if (xvalue < minxpos) minxpos = xvalue;
11007 						if (xvalue > maxxpos) maxxpos = xvalue;
11008 					}
11009 					if (minypos > maxypos) minypos = maxypos = yvalue; else
11010 					{
11011 						if (yvalue < minypos) minypos = yvalue;
11012 						if (yvalue > maxypos) maxypos = yvalue;
11013 					}
11014 					if (gotxpos == 0)
11015 					{
11016 						xpos = xvalue;
11017 						gotxpos = 1;
11018 					} else if (gotxpos == 1)
11019 					{
11020 						if (xpos != xvalue) gotxpos = -1;
11021 					}
11022 					if (gotypos == 0)
11023 					{
11024 						ypos = yvalue;
11025 						gotypos = 1;
11026 					} else if (gotypos == 1)
11027 					{
11028 						if (ypos != yvalue) gotypos = -1;
11029 					}
11030 				} else
11031 				{
11032 					ai = (ARCINST *)geom->entryaddr.ai;
11033 					addstringtoinfstr(infstr, _("Arc "));
11034 					addstringtoinfstr(infstr, describearcinst(ai));
11035 					value = ai->width - arcwidthoffset(ai);
11036 					if (minwidth > maxwidth) minwidth = maxwidth = value; else
11037 					{
11038 						if (value < minwidth) minwidth = value;
11039 						if (value > maxwidth) maxwidth = value;
11040 					}
11041 					if (gotwidth == 0)
11042 					{
11043 						width = value;
11044 						gotwidth = 1;
11045 					} else if (gotwidth == 1)
11046 					{
11047 						if (width != value) gotwidth = -1;
11048 					}
11049 				}
11050 				break;
11051 			case HIGHBBOX:
11052 				formatinfstr(infstr, _("Bounds: X from %s to %s, Y from %s to %s"),
11053 					latoa(manyhigh[i].stalx, 0), latoa(manyhigh[i].stahx, 0),
11054 					latoa(manyhigh[i].staly, 0), latoa(manyhigh[i].stahy, 0));
11055 				break;
11056 			case HIGHLINE:
11057 				formatinfstr(infstr, _("Line (%s, %s) to (%s, %s)"),
11058 					latoa(manyhigh[i].stalx, 0), latoa(manyhigh[i].staly, 0),
11059 					latoa(manyhigh[i].stahx, 0), latoa(manyhigh[i].stahy, 0));
11060 				break;
11061 			case HIGHTEXT:
11062 				if (manyhigh[i].fromport != NOPORTPROTO)
11063 				{
11064 					formatinfstr(infstr, _("Export "));
11065 					addstringtoinfstr(infstr, manyhigh[i].fromport->protoname);
11066 					break;
11067 				}
11068 				if (manyhigh[i].fromvar != NOVARIABLE)
11069 				{
11070 					if (manyhigh[i].fromport != NOPORTPROTO)
11071 					{
11072 						formatinfstr(infstr, _("Text on export %s"),
11073 							manyhigh[i].fromport->protoname);
11074 						break;
11075 					}
11076 					if (manyhigh[i].fromgeom == NOGEOM)
11077 					{
11078 						formatinfstr(infstr, _("Text on cell %s"),
11079 							describenodeproto(manyhigh[i].cell));
11080 						break;
11081 					}
11082 					if (!manyhigh[i].fromgeom->entryisnode)
11083 					{
11084 						ai = (ARCINST *)manyhigh[i].fromgeom->entryaddr.ai;
11085 						formatinfstr(infstr, _("Text on arc %s"), describearcinst(ai));
11086 						break;
11087 					}
11088 					ni = (NODEINST *)manyhigh[i].fromgeom->entryaddr.ni;
11089 					formatinfstr(infstr, _("Text on node %s"), describenodeinst(ni));
11090 					break;
11091 				}
11092 				addstringtoinfstr(infstr, _("Text object"));
11093 				break;
11094 		}
11095 		if (whichone[i] != 0)
11096 			formatinfstr(infstr, x_(" (%ld of %ld)"), whichone[i], oftotal[i]);
11097 		DiaStuffLine(dia, DGIM_OBJECTLIST, returninfstr(infstr));
11098 	}
11099 	DiaSelectLine(dia, DGIM_OBJECTLIST, 0);
11100 
11101 	if (gotxpos == 1)
11102 	{
11103 		DiaSetText(dia, DGIM_NODEXPOS, latoa(xpos, 0));
11104 		DiaSetText(dia, DGIM_NODEXPRANGE, _("All the same"));
11105 	} else if (minxpos <= maxxpos)
11106 	{
11107 		esnprintf(buf, 100, x_("%s to %s"), latoa(minxpos, 0), latoa(maxxpos, 0));
11108 		DiaSetText(dia, DGIM_NODEXPRANGE, buf);
11109 	}
11110 	if (gotypos == 1)
11111 	{
11112 		DiaSetText(dia, DGIM_NODEYPOS, latoa(ypos, 0));
11113 		DiaSetText(dia, DGIM_NODEYPRANGE, _("All the same"));
11114 	} else if (minypos <= maxypos)
11115 	{
11116 		esnprintf(buf, 100, x_("%s to %s"), latoa(minypos, 0), latoa(maxypos, 0));
11117 		DiaSetText(dia, DGIM_NODEYPRANGE, buf);
11118 	}
11119 	if (gotxsize == 1)
11120 	{
11121 		DiaSetText(dia, DGIM_NODEXSIZE, latoa(xsize, 0));
11122 		DiaSetText(dia, DGIM_NODEXSRANGE, _("All the same"));
11123 	} else if (minxsize <= maxxsize)
11124 	{
11125 		esnprintf(buf, 100, x_("%s to %s"), latoa(minxsize, 0), latoa(maxxsize, 0));
11126 		DiaSetText(dia, DGIM_NODEXSRANGE, buf);
11127 	}
11128 	if (gotysize == 1)
11129 	{
11130 		DiaSetText(dia, DGIM_NODEYSIZE, latoa(ysize, 0));
11131 		DiaSetText(dia, DGIM_NODEYSRANGE, _("All the same"));
11132 	} else if (minysize <= maxysize)
11133 	{
11134 		esnprintf(buf, 100, x_("%s to %s"), latoa(minysize, 0), latoa(maxysize, 0));
11135 		DiaSetText(dia, DGIM_NODEYSRANGE, buf);
11136 	}
11137 	if (gotwidth == 1)
11138 	{
11139 		DiaSetText(dia, DGIM_ARCWIDTH, latoa(width, 0));
11140 		DiaSetText(dia, DGIM_ARCWIDRANGE, _("All the same"));
11141 	} else if (minwidth <= maxwidth)
11142 	{
11143 		esnprintf(buf, 100, x_("%s to %s"), latoa(minwidth, 0), latoa(maxwidth, 0));
11144 		DiaSetText(dia, DGIM_ARCWIDRANGE, buf);
11145 	}
11146 }
11147 /* Text info */
11148 static DIALOGITEM us_showtextdialogitems[] =
11149 {
11150  /*  1 */ {0, {480,236,504,308}, BUTTON, N_("OK")},
11151  /*  2 */ {0, {480,20,504,92}, BUTTON, N_("Cancel")},
11152  /*  3 */ {0, {200,8,216,64}, RADIO, N_("Left")},
11153  /*  4 */ {0, {40,8,88,340}, EDITTEXT, x_("")},
11154  /*  5 */ {0, {332,64,348,112}, EDITTEXT, x_("")},
11155  /*  6 */ {0, {136,8,152,80}, RADIO, N_("Center")},
11156  /*  7 */ {0, {152,8,168,80}, RADIO, N_("Bottom")},
11157  /*  8 */ {0, {168,8,184,64}, RADIO, N_("Top")},
11158  /*  9 */ {0, {184,8,200,72}, RADIO, N_("Right")},
11159  /* 10 */ {0, {216,8,232,104}, RADIO, N_("Lower right")},
11160  /* 11 */ {0, {232,8,248,104}, RADIO, N_("Lower left")},
11161  /* 12 */ {0, {248,8,264,104}, RADIO, N_("Upper right")},
11162  /* 13 */ {0, {264,8,280,96}, RADIO, N_("Upper left")},
11163  /* 14 */ {0, {280,8,296,80}, RADIO, N_("Boxed")},
11164  /* 15 */ {0, {332,120,348,280}, RADIO, N_("Points (max 63)")},
11165  /* 16 */ {0, {120,16,136,110}, MESSAGE, N_("Text corner:")},
11166  /* 17 */ {0, {164,244,180,324}, EDITTEXT, x_("")},
11167  /* 18 */ {0, {188,244,204,324}, EDITTEXT, x_("")},
11168  /* 19 */ {0, {164,152,180,241}, MESSAGE, N_("X offset:")},
11169  /* 20 */ {0, {188,152,204,241}, MESSAGE, N_("Y offset:")},
11170  /* 21 */ {0, {136,112,168,144}, ICON, (CHAR *)us_icon200},
11171  /* 22 */ {0, {168,112,200,144}, ICON, (CHAR *)us_icon201},
11172  /* 23 */ {0, {200,112,232,144}, ICON, (CHAR *)us_icon202},
11173  /* 24 */ {0, {232,112,264,144}, ICON, (CHAR *)us_icon203},
11174  /* 25 */ {0, {264,112,296,144}, ICON, (CHAR *)us_icon204},
11175  /* 26 */ {0, {4,8,36,340}, MESSAGE, x_("")},
11176  /* 27 */ {0, {128,194,148,294}, BUTTON, N_("Edit Text")},
11177  /* 28 */ {0, {236,152,252,340}, CHECK, N_("Visible only inside cell")},
11178  /* 29 */ {0, {96,8,112,340}, MESSAGE, x_("")},
11179  /* 30 */ {0, {212,232,228,340}, POPUP, x_("")},
11180  /* 31 */ {0, {212,152,228,231}, MESSAGE, N_("Language:")},
11181  /* 32 */ {0, {308,8,324,88}, MESSAGE, N_("Show:")},
11182  /* 33 */ {0, {308,92,324,280}, POPUP, x_("")},
11183  /* 34 */ {0, {356,64,372,112}, EDITTEXT, x_("")},
11184  /* 35 */ {0, {356,120,372,280}, RADIO, N_("Lambda (max 127.75)")},
11185  /* 36 */ {0, {380,92,396,280}, POPUP, x_("")},
11186  /* 37 */ {0, {380,8,396,87}, MESSAGE, N_("Type face:")},
11187  /* 38 */ {0, {404,8,420,91}, CHECK, N_("Italic")},
11188  /* 39 */ {0, {404,104,420,187}, CHECK, N_("Bold")},
11189  /* 40 */ {0, {404,196,420,279}, CHECK, N_("Underline")},
11190  /* 41 */ {0, {344,8,360,56}, MESSAGE, N_("Size")},
11191  /* 42 */ {0, {268,260,292,332}, BUTTON, N_("Node Info")},
11192  /* 43 */ {0, {268,160,292,232}, BUTTON, N_("See Node")},
11193  /* 44 */ {0, {428,92,444,280}, POPUP, x_("")},
11194  /* 45 */ {0, {428,8,444,87}, MESSAGE, N_("Rotation:")},
11195  /* 46 */ {0, {452,92,468,280}, POPUP, x_("")},
11196  /* 47 */ {0, {452,8,468,87}, MESSAGE, N_("Units:")}
11197 };
11198 static DIALOG us_showtextdialog = {{50,75,563,424}, N_("Information on Highlighted Text"), 0, 47, us_showtextdialogitems, 0, 0};
11199 
11200 /* special items for the "Text Get Info" dialog: */
11201 #define DGIT_CORNERLEFT       3		/* left (radio) */
11202 #define DGIT_TEXTVALUE        4		/* text name (edit text) */
11203 #define DGIT_TEXTSIZEABS      5		/* Absolute text size (edit text) */
11204 #define DGIT_CORNERCENTER     6		/* center (radio) */
11205 #define DGIT_CORNERBOT        7		/* bottom (radio) */
11206 #define DGIT_CORNERTOP        8		/* top (radio) */
11207 #define DGIT_CORNERRIGHT      9		/* right (radio) */
11208 #define DGIT_CORNERLOWRIGHT  10		/* lower right (radio) */
11209 #define DGIT_CORNERLOWLEFT   11		/* lower left (radio) */
11210 #define DGIT_CORNERUPRIGHT   12		/* upper right (radio) */
11211 #define DGIT_CORNERUPLEFT    13		/* upper left (radio) */
11212 #define DGIT_CORNERBOXED     14		/* boxed (radio) */
11213 #define DGIT_TEXTSIZEABS_L   15		/* Absolute text size (radio) */
11214 #define DGIT_XOFFSET         17		/* X offset (edit text) */
11215 #define DGIT_YOFFSET         18		/* Y offset (edit text) */
11216 #define DGIT_XOFFSET_L       19		/* X offset label (stat text) */
11217 #define DGIT_YOFFSET_L       20		/* Y offset label (stat text) */
11218 #define DGIT_LOWICON         21		/* first icon (icon) */
11219 #define DGIT_HIGHICON        25		/* last icon (icon) */
11220 #define DGIT_TEXTTYPE        26		/* title (stat text) */
11221 #define DGIT_EDITTEXT        27		/* Edit text (button) */
11222 #define DGIT_INSIDECELL      28		/* Only inside cell (check) */
11223 #define DGIT_EVALUATION      29		/* Evaluated value (stat text) */
11224 #define DGIT_LANGUAGE        30		/* Language (popup) */
11225 #define DGIT_LANGUAGE_L      31		/* Language label (stat text) */
11226 #define DGIT_WHATTOSHOW_L    32		/* What to show label (stat text) */
11227 #define DGIT_WHATTOSHOW      33		/* What to show (popup) */
11228 #define DGIT_TEXTSIZEREL     34		/* Relative text size (edit text) */
11229 #define DGIT_TEXTSIZEREL_L   35		/* Relative text size label (radio) */
11230 #define DGIT_TEXTFACE        36		/* Typeface (popup) */
11231 #define DGIT_TEXTFACE_L      37		/* Typeface label (stat text) */
11232 #define DGIT_TEXTITALIC      38		/* Italic type (check) */
11233 #define DGIT_TEXTBOLD        39		/* Bold type (check) */
11234 #define DGIT_TEXTUNDERLINE   40		/* Underline type (check) */
11235 #define DGIT_OBJECTINFO      42		/* Get Info on object (button) */
11236 #define DGIT_OBJECTHIGH      43		/* Highlight object (button) */
11237 #define DGIT_ROTATION        44		/* Text rotation (popup) */
11238 #define DGIT_UNITS           46		/* Text units (popup) */
11239 #define DGIT_UNITS_L         47		/* Text units label (stat text) */
11240 
us_getinfotext(HIGHLIGHT * high,BOOLEAN canspecialize)11241 void us_getinfotext(HIGHLIGHT *high, BOOLEAN canspecialize)
11242 {
11243 	REGISTER INTBIG itemHit, j, i, height, objtype, lambda, savetype,
11244 		xcur, ycur, lindex, xc, yc, maxshowoptions;
11245 	INTBIG x, y, nlx, nhx, nly, nhy, oldtype, newval;
11246 	REGISTER BOOLEAN changed, posnotoffset, cantbox;
11247 	UINTBIG descript[TEXTDESCRIPTSIZE], newdescript[TEXTDESCRIPTSIZE], newtype;
11248 	CHAR *str, *newstr, *formerstr, *newlang[15], **languages, buf[30];
11249 	RECTAREA itemRect;
11250 	HIGHLIGHT newhigh;
11251 	REGISTER NODEINST *ni;
11252 	REGISTER LIBRARY *lib;
11253 	REGISTER NODEPROTO *cell;
11254 	REGISTER VARIABLE *var, *noevar;
11255 	REGISTER TECHNOLOGY *tech;
11256 	static CHAR *whattodisplay[] = {N_("Value"), N_("Name&Value"),
11257 		N_("Name,Inherit,Value"), N_("Name,Inherit-All,Value")};
11258 	static struct butlist poslist[10] =
11259 	{
11260 		{VTPOSCENT,      DGIT_CORNERCENTER},
11261 		{VTPOSUP,        DGIT_CORNERBOT},
11262 		{VTPOSDOWN,      DGIT_CORNERTOP},
11263 		{VTPOSLEFT,      DGIT_CORNERRIGHT},
11264 		{VTPOSRIGHT,     DGIT_CORNERLEFT},
11265 		{VTPOSUPLEFT,    DGIT_CORNERLOWRIGHT},
11266 		{VTPOSUPRIGHT,   DGIT_CORNERLOWLEFT},
11267 		{VTPOSDOWNLEFT,  DGIT_CORNERUPRIGHT},
11268 		{VTPOSDOWNRIGHT, DGIT_CORNERUPLEFT},
11269 		{VTPOSBOXED,     DGIT_CORNERBOXED}
11270 	};
11271 	REGISTER void *infstr;
11272 	REGISTER void *dia;
11273 
11274 	/* display text */
11275 	var = high->fromvar;
11276 	tech = us_hightech(high);
11277 	cell = us_highcell(high);
11278 	if (cell == NONODEPROTO) lib = el_curlib; else
11279 		lib = cell->lib;
11280 	lambda = lib->lambda[tech->techindex];
11281 
11282 	objtype = VUNKNOWN;
11283 	if (var == NOVARIABLE)
11284 	{
11285 		/* this must be a cell name */
11286 		if (high->fromgeom == NOGEOM || !high->fromgeom->entryisnode)
11287 			return;
11288 
11289 		/* get information about the cell name */
11290 		ni = high->fromgeom->entryaddr.ni;
11291 		str = describenodeproto(ni->proto);
11292 		TDCOPY(descript, ni->textdescript);
11293 		if (ni->rotation != 0 || ni->transpose != 0)
11294 			us_rotatedescript(high->fromgeom, descript);
11295 		objtype = VNODEINST;
11296 
11297 		/* display the text dialog box */
11298 		us_showtextdialog.list[DGIT_OBJECTINFO-1].msg = _("Node Info");
11299 		us_showtextdialog.list[DGIT_OBJECTHIGH-1].msg = _("See Node");
11300 		dia = DiaInitDialog(&us_showtextdialog);
11301 		if (dia == 0) return;
11302 		DiaSetText(dia, DGIT_TEXTVALUE, str);
11303 		DiaNoEditControl(dia, DGIT_TEXTVALUE);
11304 		DiaSetText(dia, DGIT_TEXTTYPE, _("Text information for cell name:"));
11305 		DiaDimItem(dia, DGIT_EDITTEXT);
11306 		DiaDimItem(dia, DGIT_INSIDECELL);
11307 		languages = us_languagechoices();
11308 		DiaSetPopup(dia, DGIT_LANGUAGE, 4, languages);
11309 		DiaDimItem(dia, DGIT_LANGUAGE);
11310 		DiaDimItem(dia, DGIT_LANGUAGE_L);
11311 		DiaDimItem(dia, DGIT_WHATTOSHOW_L);
11312 		DiaDimItem(dia, DGIT_WHATTOSHOW);
11313 		DiaDimItem(dia, DGIT_UNITS);
11314 		DiaDimItem(dia, DGIT_UNITS_L);
11315 		for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_rotationtypes[i]);
11316 		DiaSetPopup(dia, DGIT_ROTATION, 4, newlang);
11317 
11318 		/* set the orientation button */
11319 		for(i=0; i<10; i++)
11320 			if (poslist[i].value == TDGETPOS(descript))
11321 		{
11322 			DiaSetControl(dia, poslist[i].button, 1);
11323 			break;
11324 		}
11325 
11326 		/* set the size fields */
11327 		i = TDGETSIZE(descript);
11328 		if (TXTGETPOINTS(i) != 0)
11329 		{
11330 			/* show point size */
11331 			esnprintf(buf, 30, x_("%ld"), TXTGETPOINTS(i));
11332 			DiaSetText(dia, DGIT_TEXTSIZEABS, buf);
11333 			DiaSetControl(dia, DGIT_TEXTSIZEABS_L, 1);
11334 
11335 			/* figure out how many lambda the point value is */
11336 			height = TXTGETPOINTS(i);
11337 			if (el_curwindowpart != NOWINDOWPART)
11338 				height = roundfloat((float)height / el_curwindowpart->scaley);
11339 			height = height * 4 / lambda;
11340 			DiaSetText(dia, DGIT_TEXTSIZEREL, frtoa(height * WHOLE / 4));
11341 		} else if (TXTGETQLAMBDA(i) != 0)
11342 		{
11343 			/* show lambda value */
11344 			height = TXTGETQLAMBDA(i);
11345 			DiaSetText(dia, DGIT_TEXTSIZEREL, frtoa(height * WHOLE / 4));
11346 			DiaSetControl(dia, DGIT_TEXTSIZEREL_L, 1);
11347 
11348 			/* figure out how many points the lambda value is */
11349 			height = height * lambda / 4;
11350 			if (el_curwindowpart != NOWINDOWPART)
11351 				height = applyyscale(el_curwindowpart, height);
11352 			esnprintf(buf, 30, x_("%ld"), height);
11353 			DiaSetText(dia, DGIT_TEXTSIZEABS, buf);
11354 		}
11355 		if (graphicshas(CANCHOOSEFACES))
11356 		{
11357 			DiaUnDimItem(dia, DGIT_TEXTFACE_L);
11358 			us_setpopupface(DGIT_TEXTFACE, TDGETFACE(descript), TRUE, dia);
11359 		} else
11360 		{
11361 			DiaDimItem(dia, DGIT_TEXTFACE_L);
11362 		}
11363 		i = TDGETROTATION(descript);
11364 		DiaSetPopupEntry(dia, DGIT_ROTATION, i);
11365 		if (graphicshas(CANMODIFYFONTS))
11366 		{
11367 			DiaUnDimItem(dia, DGIT_TEXTITALIC);
11368 			DiaUnDimItem(dia, DGIT_TEXTBOLD);
11369 			DiaUnDimItem(dia, DGIT_TEXTUNDERLINE);
11370 			if (TDGETITALIC(descript) != 0) DiaSetControl(dia, DGIT_TEXTITALIC, 1);
11371 			if (TDGETBOLD(descript) != 0) DiaSetControl(dia, DGIT_TEXTBOLD, 1);
11372 			if (TDGETUNDERLINE(descript) != 0) DiaSetControl(dia, DGIT_TEXTUNDERLINE, 1);
11373 		} else
11374 		{
11375 			DiaDimItem(dia, DGIT_TEXTITALIC);
11376 			DiaDimItem(dia, DGIT_TEXTBOLD);
11377 			DiaDimItem(dia, DGIT_TEXTUNDERLINE);
11378 		}
11379 
11380 		/* set offsets */
11381 		i = TDGETXOFF(descript);
11382 		DiaSetText(dia, DGIT_XOFFSET, latoa(i * lambda / 4, lambda));
11383 		j = TDGETYOFF(descript);
11384 		DiaSetText(dia, DGIT_YOFFSET, latoa(j * lambda / 4, lambda));
11385 
11386 		/* loop until done */
11387 		changed = FALSE;
11388 		for(;;)
11389 		{
11390 			itemHit = DiaNextHit(dia);
11391 			if (itemHit == OK || itemHit == CANCEL || itemHit == DGIT_OBJECTINFO) break;
11392 			if (itemHit == DGIT_OBJECTHIGH)
11393 			{
11394 				if (high->fromgeom != NOGEOM)
11395 				{
11396 					us_clearhighlightcount();
11397 					newhigh.status = HIGHFROM;
11398 					newhigh.cell = ni->parent;
11399 					newhigh.fromgeom = ni->geom;
11400 					newhigh.fromport = NOPORTPROTO;
11401 					newhigh.frompoint = 0;
11402 					newhigh.fromvar = NOVARIABLE;
11403 					newhigh.fromvarnoeval = NOVARIABLE;
11404 					us_addhighlight(&newhigh);
11405 					us_showallhighlight();
11406 					us_endchanges(NOWINDOWPART);
11407 				}
11408 				continue;
11409 			}
11410 			if (itemHit >= DGIT_LOWICON && itemHit <= DGIT_HIGHICON)
11411 			{
11412 				DiaItemRect(dia, itemHit, &itemRect);
11413 				DiaGetMouse(dia, &x, &y);
11414 				itemHit = (itemHit-DGIT_LOWICON) * 2;
11415 				if (y > (itemRect.top + itemRect.bottom) / 2) itemHit++;
11416 				itemHit = poslist[itemHit].button;
11417 			}
11418 			for(i=0; i<10; i++) if (itemHit == poslist[i].button)
11419 			{
11420 				for(j=0; j<10; j++) DiaSetControl(dia, poslist[j].button, 0);
11421 				DiaSetControl(dia, itemHit, 1);
11422 				changed = TRUE;
11423 				continue;
11424 			}
11425 			if (itemHit == DGIT_XOFFSET || itemHit == DGIT_YOFFSET ||
11426 				itemHit == DGIT_TEXTFACE || itemHit == DGIT_ROTATION) changed = TRUE;
11427 			if (itemHit == DGIT_TEXTSIZEREL) itemHit = DGIT_TEXTSIZEREL_L;
11428 			if (itemHit == DGIT_TEXTSIZEABS) itemHit = DGIT_TEXTSIZEABS_L;
11429 			if (itemHit == DGIT_TEXTSIZEREL_L || itemHit == DGIT_TEXTSIZEABS_L)
11430 			{
11431 				DiaSetControl(dia, DGIT_TEXTSIZEREL_L, 0);
11432 				DiaSetControl(dia, DGIT_TEXTSIZEABS_L, 0);
11433 				DiaSetControl(dia, itemHit, 1);
11434 				changed = TRUE;
11435 				continue;
11436 			}
11437 			if (itemHit == DGIT_TEXTITALIC || itemHit == DGIT_TEXTBOLD ||
11438 				itemHit == DGIT_TEXTUNDERLINE)
11439 			{
11440 				DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
11441 				changed = TRUE;
11442 				continue;
11443 			}
11444 		}
11445 		if (itemHit != CANCEL)
11446 		{
11447 			/* get the new descriptor */
11448 			TDCOPY(newdescript, descript);
11449 			if (changed)
11450 			{
11451 				xcur = atola(DiaGetText(dia, DGIT_XOFFSET), 0);
11452 				ycur = atola(DiaGetText(dia, DGIT_YOFFSET), 0);
11453 				us_setdescriptoffset(newdescript, xcur*4/lambda, ycur*4/lambda);
11454 				if (DiaGetControl(dia, DGIT_TEXTSIZEABS_L) != 0)
11455 				{
11456 					j = eatoi(DiaGetText(dia, DGIT_TEXTSIZEABS));
11457 					if (j <= 0) j = 4;
11458 					if (j >= TXTMAXPOINTS) j = TXTMAXPOINTS;
11459 					TDSETSIZE(newdescript, TXTSETPOINTS(j));
11460 				} else
11461 				{
11462 					j = atofr(DiaGetText(dia, DGIT_TEXTSIZEREL)) * 4 / WHOLE;
11463 					if (j <= 0) j = 4;
11464 					if (j >= TXTMAXQLAMBDA) j = TXTMAXQLAMBDA;
11465 					TDSETSIZE(newdescript, TXTSETQLAMBDA(j));
11466 				}
11467 				if (DiaGetControl(dia, DGIT_TEXTITALIC) != 0)
11468 					TDSETITALIC(newdescript, VTITALIC); else
11469 						TDSETITALIC(newdescript, 0);
11470 				if (DiaGetControl(dia, DGIT_TEXTBOLD) != 0)
11471 					TDSETBOLD(newdescript, VTBOLD); else
11472 						TDSETBOLD(newdescript, 0);
11473 				if (DiaGetControl(dia, DGIT_TEXTUNDERLINE) != 0)
11474 					TDSETUNDERLINE(newdescript, VTUNDERLINE); else
11475 						TDSETUNDERLINE(newdescript, 0);
11476 				if (graphicshas(CANCHOOSEFACES))
11477 				{
11478 					i = us_getpopupface(DGIT_TEXTFACE, dia);
11479 					TDSETFACE(newdescript, i);
11480 				}
11481 				i = DiaGetPopupEntry(dia, DGIT_ROTATION);
11482 				TDSETROTATION(newdescript, i);
11483 				for(j=0; j<10; j++)
11484 					if (DiaGetControl(dia, poslist[j].button) != 0) break;
11485 				TDSETPOS(newdescript, poslist[j].value);
11486 				if (DiaGetControl(dia, DGIT_INSIDECELL) != 0)
11487 					TDSETINTERIOR(newdescript, VTINTERIOR); else
11488 						TDSETINTERIOR(newdescript, 0);
11489 
11490 				/* if the node is rotated, modify grab-point */
11491 				if (ni->rotation != 0 || ni->transpose != 0)
11492 					us_rotatedescriptI(high->fromgeom, newdescript);
11493 			}
11494 
11495 			/* see if changes were made */
11496 			if (newdescript != descript)
11497 			{
11498 				/* save highlighting */
11499 				us_pushhighlight();
11500 				us_clearhighlightcount();
11501 
11502 				/* set the new descriptor */
11503 				startobjectchange((INTBIG)high->fromgeom->entryaddr.blind, objtype);
11504 				us_modifytextdescript(high, newdescript);
11505 				endobjectchange((INTBIG)high->fromgeom->entryaddr.blind, objtype);
11506 
11507 				/* restore highlighting */
11508 				us_pophighlight(TRUE);
11509 			}
11510 		}
11511 		DiaDoneDialog(dia);
11512 		if (itemHit == DGIT_OBJECTINFO)
11513 		{
11514 			us_clearhighlightcount();
11515 			newhigh.status = HIGHFROM;
11516 			newhigh.cell = ni->parent;
11517 			newhigh.fromgeom = ni->geom;
11518 			newhigh.fromport = NOPORTPROTO;
11519 			newhigh.frompoint = 0;
11520 			newhigh.fromvar = NOVARIABLE;
11521 			newhigh.fromvarnoeval = NOVARIABLE;
11522 			us_addhighlight(&newhigh);
11523 			us_showallhighlight();
11524 			us_endchanges(NOWINDOWPART);
11525 			us_getinfonode(ni, FALSE);
11526 		}
11527 		return;
11528 	}
11529 
11530 	/* handle standard variables */
11531 	noevar = var;
11532 	if (high->fromvarnoeval != NOVARIABLE) noevar = high->fromvarnoeval;
11533 
11534 	/* special case if known variables are selected */
11535 	if (canspecialize)
11536 	{
11537 		if (high->fromgeom != NOGEOM)
11538 		{
11539 			if (TDGETUNITS(var->textdescript) == VTUNITSRES)
11540 			{
11541 				us_resistancedlog(high->fromgeom, var);
11542 				return;
11543 			}
11544 			if (TDGETUNITS(var->textdescript) == VTUNITSCAP)
11545 			{
11546 				us_capacitancedlog(high->fromgeom, var);
11547 				return;
11548 			}
11549 			if (TDGETUNITS(var->textdescript) == VTUNITSIND)
11550 			{
11551 				us_inductancedlog(high->fromgeom, var);
11552 				return;
11553 			}
11554 			if (high->fromgeom->entryisnode)
11555 			{
11556 				ni = high->fromgeom->entryaddr.ni;
11557 				if (var->key == sch_globalnamekey)
11558 				{
11559 					(void)us_globalsignaldlog();
11560 					return;
11561 				}
11562 				if (var->key == sch_diodekey)
11563 				{
11564 					us_areadlog(ni);
11565 					return;
11566 				}
11567 				if (var->key == el_attrkey_length || var->key == el_attrkey_width)
11568 				{
11569 					/* must be a transistor */
11570 					if (isfet(high->fromgeom))
11571 					{
11572 						us_widlendlog(ni);
11573 						return;
11574 					}
11575 				}
11576 				if (var->key == el_attrkey_area)
11577 				{
11578 					us_areadlog(ni);
11579 					return;
11580 				}
11581 			}
11582 		}
11583 
11584 		/*
11585 		 * if this is a displayable text variable, edit it in place.
11586 		 * Can only in-place edit displayable text; with value shown; non-code; and arrays can
11587 		 * only be edited in-place if they are string arrays
11588 		 */
11589 		if ((var->type&VDISPLAY) != 0 && (noevar->type&(VCODE1|VCODE2)) == 0 &&
11590 			TDGETROTATION(var->textdescript) == 0 &&
11591 			((var->type&VTYPE) == VSTRING || (var->type&VISARRAY) == 0))
11592 		{
11593 			/* save and clear highlighting */
11594 			us_pushhighlight();
11595 			us_clearhighlightcount();
11596 
11597 			/* edit the variable */
11598 			if (high->fromport != NOPORTPROTO)
11599 			{
11600 				us_editvariabletext(var, VPORTPROTO, (INTBIG)high->fromport,
11601 					makename(var->key));
11602 			} else if (high->fromgeom == NOGEOM)
11603 			{
11604 				us_editvariabletext(var, VNODEPROTO, (INTBIG)high->cell,
11605 					makename(var->key));
11606 			} else
11607 			{
11608 				if (high->fromgeom->entryisnode) objtype = VNODEINST; else
11609 					objtype = VARCINST;
11610 				us_editvariabletext(var, objtype, (INTBIG)high->fromgeom->entryaddr.blind,
11611 					makename(var->key));
11612 			}
11613 
11614 			/* restore highlighting */
11615 			us_pophighlight(FALSE);
11616 			return;
11617 		}
11618 	}
11619 
11620 	/* prepare dialog to show appropriate buttons */
11621 	us_showtextdialog.list[DGIT_OBJECTINFO-1].msg = _("Info");
11622 	us_showtextdialog.list[DGIT_OBJECTHIGH-1].msg = _("See");
11623 	if (high->fromgeom != NOGEOM)
11624 	{
11625 		if (high->fromgeom->entryisnode)
11626 		{
11627 			objtype = VNODEINST;
11628 			if (high->fromgeom->entryaddr.ni->proto != gen_invispinprim)
11629 			{
11630 				us_showtextdialog.list[DGIT_OBJECTINFO-1].msg = _("Node Info");
11631 				us_showtextdialog.list[DGIT_OBJECTHIGH-1].msg = _("See Node");
11632 			}
11633 		} else
11634 		{
11635 			objtype = VARCINST;
11636 			us_showtextdialog.list[DGIT_OBJECTINFO-1].msg = _("Arc Info");
11637 			us_showtextdialog.list[DGIT_OBJECTHIGH-1].msg = _("See Arc");
11638 		}
11639 	}
11640 
11641 	/* display the text dialog box */
11642 	dia = DiaInitDialog(&us_showtextdialog);
11643 	if (dia == 0) return;
11644 	if (high->fromgeom == NOGEOM && TDGETISPARAM(var->textdescript) != 0)
11645 		maxshowoptions = 4; else
11646 			maxshowoptions = 2;
11647 	for(i=0; i<maxshowoptions; i++) newlang[i] = TRANSLATE(whattodisplay[i]);
11648 	DiaSetPopup(dia, DGIT_WHATTOSHOW, maxshowoptions, newlang);
11649 	languages = us_languagechoices();
11650 	DiaSetPopup(dia, DGIT_LANGUAGE, 4, languages);
11651 	DiaDimItem(dia, DGIT_EDITTEXT);
11652 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_rotationtypes[i]);
11653 	DiaSetPopup(dia, DGIT_ROTATION, 4, newlang);
11654 
11655 	/* enable items that may get dimmed */
11656 	DiaUnDimItem(dia, DGIT_INSIDECELL);
11657 	DiaUnDimItem(dia, DGIT_LANGUAGE);
11658 	DiaUnDimItem(dia, DGIT_LANGUAGE_L);
11659 	DiaUnDimItem(dia, DGIT_WHATTOSHOW_L);
11660 	DiaUnDimItem(dia, DGIT_WHATTOSHOW);
11661 	DiaUnDimItem(dia, DGIT_UNITS);
11662 	DiaUnDimItem(dia, DGIT_UNITS_L);
11663 	DiaUnDimItem(dia, DGIT_OBJECTINFO);
11664 	DiaUnDimItem(dia, DGIT_OBJECTHIGH);
11665 	DiaUnDimItem(dia, DGIT_CORNERBOXED);
11666 
11667 	/* describe the text */
11668 	posnotoffset = FALSE;
11669 	cantbox = FALSE;
11670 	infstr = initinfstr();
11671 	if (high->fromgeom == NOGEOM)
11672 	{
11673 		DiaDimItem(dia, DGIT_OBJECTINFO);
11674 		DiaDimItem(dia, DGIT_OBJECTHIGH);
11675 		DiaSetText(dia, DGIT_XOFFSET_L, _("X position:"));
11676 		DiaSetText(dia, DGIT_YOFFSET_L, _("Y position:"));
11677 		formatinfstr(infstr, _("%s on cell '%s'"), us_trueattributename(var),
11678 			describenodeproto(high->cell));
11679 	} else
11680 	{
11681 		lambda = figurelambda(high->fromgeom);
11682 		if (high->fromport != NOPORTPROTO)
11683 		{
11684 			DiaDimItem(dia, DGIT_OBJECTINFO);
11685 			DiaDimItem(dia, DGIT_OBJECTHIGH);
11686 			formatinfstr(infstr, _("%s on port '%s'"), us_trueattributename(var),
11687 				high->fromport->protoname);
11688 		} else
11689 		{
11690 			if (high->fromgeom->entryisnode)
11691 			{
11692 				ni = high->fromgeom->entryaddr.ni;
11693 				if (ni->proto == gen_invispinprim)
11694 				{
11695 					addstringtoinfstr(infstr, us_invisiblepintextname(var));
11696 					DiaSetText(dia, DGIT_XOFFSET_L, _("X position:"));
11697 					DiaSetText(dia, DGIT_YOFFSET_L, _("Y position:"));
11698 					posnotoffset = TRUE;
11699 					DiaDimItem(dia, DGIT_OBJECTINFO);
11700 					DiaDimItem(dia, DGIT_OBJECTHIGH);
11701 				} else
11702 				{
11703 					formatinfstr(infstr, _("%s on node '%s'"), us_trueattributename(var),
11704 						us_describenodeinsttype(ni->proto, ni, ni->userbits&NTECHBITS));
11705 				}
11706 				boundobj(high->fromgeom, &nlx, &nhx, &nly, &nhy);
11707 				if (nhx == nlx || nhy == nly)
11708 				{
11709 					cantbox = TRUE;
11710 					DiaDimItem(dia, DGIT_CORNERBOXED);
11711 				}
11712 			} else
11713 			{
11714 				formatinfstr(infstr, _("%s on arc '%s'"), us_trueattributename(var),
11715 					describearcinst(high->fromgeom->entryaddr.ai));
11716 			}
11717 		}
11718 	}
11719 	DiaSetText(dia, DGIT_TEXTTYPE, returninfstr(infstr));
11720 
11721 	/* describe how the text is shown */
11722 	TDCOPY(descript, noevar->textdescript);
11723 	switch (TDGETDISPPART(descript))
11724 	{
11725 		case VTDISPLAYVALUE:         DiaSetPopupEntry(dia, DGIT_WHATTOSHOW, 0);   break;
11726 		case VTDISPLAYNAMEVALUE:     DiaSetPopupEntry(dia, DGIT_WHATTOSHOW, 1);   break;
11727 		case VTDISPLAYNAMEVALINH:
11728 			if (maxshowoptions == 4)
11729 				DiaSetPopupEntry(dia, DGIT_WHATTOSHOW, 2);
11730 			break;
11731 		case VTDISPLAYNAMEVALINHALL:
11732 			if (maxshowoptions == 4)
11733 				DiaSetPopupEntry(dia, DGIT_WHATTOSHOW, 3);
11734 			break;
11735 	}
11736 
11737 	/* describe the text units */
11738 	for(i=0; i<8; i++) newlang[i] = TRANSLATE(us_unitnames[i]);
11739 	DiaSetPopup(dia, DGIT_UNITS, 8, newlang);
11740 	DiaSetPopupEntry(dia, DGIT_UNITS, TDGETUNITS(descript));
11741 
11742 	/* handle arrays of text */
11743 	lindex = -1;
11744 	DiaEditControl(dia, DGIT_TEXTVALUE);
11745 	if ((var->type&VISARRAY) != 0)
11746 	{
11747 		if (getlength(var) == 1) lindex = 0; else
11748 		{
11749 			DiaNoEditControl(dia, DGIT_TEXTVALUE);
11750 			DiaUnDimItem(dia, DGIT_EDITTEXT);
11751 		}
11752 	}
11753 
11754 	/* show the value */
11755 	TDSETDISPPART(noevar->textdescript, 0);
11756 	savetype = noevar->type;
11757 	if ((noevar->type&(VCODE1|VCODE2)) != 0)
11758 	{
11759 		/* code: show it unevaluated */
11760 		noevar->type = (noevar->type & ~(VCODE1|VCODE2|VTYPE)) | VSTRING;
11761 		(void)allocstring(&formerstr, describevariable(noevar, lindex, -1),
11762 			el_tempcluster);
11763 	} else
11764 	{
11765 		/* not code: show values */
11766 		str = describevariable(noevar, lindex, -1);
11767 		(void)allocstring(&formerstr, str, el_tempcluster);
11768 	}
11769 	str = formerstr;
11770 	noevar->type = savetype;
11771 	TDCOPY(noevar->textdescript, descript);
11772 	DiaSetText(dia, -DGIT_TEXTVALUE, str);
11773 
11774 	/* set the "language" popup */
11775 	i = noevar->type & (VCODE1|VCODE2);
11776 	switch (i)
11777 	{
11778 		case 0:     DiaSetPopupEntry(dia, DGIT_LANGUAGE, 0);   break;
11779 		case VTCL:  DiaSetPopupEntry(dia, DGIT_LANGUAGE, 1);   break;
11780 		case VLISP: DiaSetPopupEntry(dia, DGIT_LANGUAGE, 2);   break;
11781 		case VJAVA: DiaSetPopupEntry(dia, DGIT_LANGUAGE, 3);   break;
11782 	}
11783 	if (i != 0)
11784 	{
11785 		infstr = initinfstr();
11786 		addstringtoinfstr(infstr, _("Evaluation: "));
11787 		addstringtoinfstr(infstr, describevariable(var, -1, 0));
11788 		DiaSetText(dia, DGIT_EVALUATION, returninfstr(infstr));
11789 	}
11790 	if ((var->type&VISARRAY) != 0 && lindex < 0)
11791 	{
11792 		DiaDimItem(dia, DGIT_LANGUAGE);
11793 		DiaDimItem(dia, DGIT_LANGUAGE_L);
11794 	}
11795 
11796 	/* if this is on a node and the node is rotated, modify grab-point */
11797 	if (high->fromgeom != NOGEOM && high->fromgeom->entryisnode)
11798 	{
11799 		ni = high->fromgeom->entryaddr.ni;
11800 		if (ni->rotation != 0 || ni->transpose != 0)
11801 			us_rotatedescript(high->fromgeom, descript);
11802 	}
11803 
11804 	/* set the orientation button */
11805 	for(i=0; i<10; i++)
11806 		if (poslist[i].value == TDGETPOS(descript))
11807 	{
11808 		DiaSetControl(dia, poslist[i].button, 1);
11809 		break;
11810 	}
11811 
11812 	/* set the size fields */
11813 	i = TDGETSIZE(descript);
11814 	if (TXTGETPOINTS(i) != 0)
11815 	{
11816 		/* show point size */
11817 		esnprintf(buf, 30, x_("%ld"), TXTGETPOINTS(i));
11818 		DiaSetText(dia, DGIT_TEXTSIZEABS, buf);
11819 		DiaSetControl(dia, DGIT_TEXTSIZEABS_L, 1);
11820 
11821 		/* figure out how many lambda the point value is */
11822 		height = TXTGETPOINTS(i);
11823 		if (el_curwindowpart != NOWINDOWPART)
11824 			height = roundfloat((float)height / el_curwindowpart->scaley);
11825 		height = height * 4 / lambda;
11826 		DiaSetText(dia, DGIT_TEXTSIZEREL, frtoa(height * WHOLE / 4));
11827 	} else if (TXTGETQLAMBDA(i) != 0)
11828 	{
11829 		/* show lambda value */
11830 		height = TXTGETQLAMBDA(i);
11831 		DiaSetText(dia, DGIT_TEXTSIZEREL, frtoa(height * WHOLE / 4));
11832 		DiaSetControl(dia, DGIT_TEXTSIZEREL_L, 1);
11833 
11834 		/* figure out how many points the lambda value is */
11835 		height = height * lambda / 4;
11836 		if (el_curwindowpart != NOWINDOWPART)
11837 			height = applyyscale(el_curwindowpart, height);
11838 		esnprintf(buf, 30, x_("%ld"), height);
11839 		DiaSetText(dia, DGIT_TEXTSIZEABS, buf);
11840 	}
11841 	if (graphicshas(CANCHOOSEFACES))
11842 	{
11843 		DiaUnDimItem(dia, DGIT_TEXTFACE_L);
11844 		us_setpopupface(DGIT_TEXTFACE, TDGETFACE(descript), TRUE, dia);
11845 	} else
11846 	{
11847 		DiaDimItem(dia, DGIT_TEXTFACE_L);
11848 	}
11849 	i = TDGETROTATION(descript);
11850 	DiaSetPopupEntry(dia, DGIT_ROTATION, i);
11851 	if (graphicshas(CANMODIFYFONTS))
11852 	{
11853 		DiaUnDimItem(dia, DGIT_TEXTITALIC);
11854 		DiaUnDimItem(dia, DGIT_TEXTBOLD);
11855 		DiaUnDimItem(dia, DGIT_TEXTUNDERLINE);
11856 		if (TDGETITALIC(descript) != 0) DiaSetControl(dia, DGIT_TEXTITALIC, 1);
11857 		if (TDGETBOLD(descript) != 0) DiaSetControl(dia, DGIT_TEXTBOLD, 1);
11858 		if (TDGETUNDERLINE(descript) != 0) DiaSetControl(dia, DGIT_TEXTUNDERLINE, 1);
11859 	} else
11860 	{
11861 		DiaDimItem(dia, DGIT_TEXTITALIC);
11862 		DiaDimItem(dia, DGIT_TEXTBOLD);
11863 		DiaDimItem(dia, DGIT_TEXTUNDERLINE);
11864 	}
11865 
11866 	/* set the interior checkbox */
11867 	if (TDGETINTERIOR(descript) != 0) DiaSetControl(dia, DGIT_INSIDECELL, 1);
11868 
11869 	/* set offsets */
11870 	if (posnotoffset)
11871 	{
11872 		ni = high->fromgeom->entryaddr.ni;
11873 		DiaSetText(dia, DGIT_XOFFSET, latoa((ni->lowx + ni->highx) / 2, lambda));
11874 		DiaSetText(dia, DGIT_YOFFSET, latoa((ni->lowy + ni->highy) / 2, lambda));
11875 	} else
11876 	{
11877 		i = TDGETXOFF(descript);
11878 		DiaSetText(dia, DGIT_XOFFSET, latoa(i * lambda / 4, lambda));
11879 		j = TDGETYOFF(descript);
11880 		DiaSetText(dia, DGIT_YOFFSET, latoa(j * lambda / 4, lambda));
11881 	}
11882 
11883 	/* loop until done */
11884 	changed = FALSE;
11885 	for(;;)
11886 	{
11887 		itemHit = DiaNextHit(dia);
11888 		if (itemHit == OK || itemHit == CANCEL ||
11889 			itemHit == DGIT_EDITTEXT || itemHit == DGIT_OBJECTINFO) break;
11890 		if (itemHit == DGIT_OBJECTHIGH)
11891 		{
11892 			if (high->fromgeom != NOGEOM)
11893 			{
11894 				us_clearhighlightcount();
11895 				newhigh.status = HIGHFROM;
11896 				newhigh.cell = geomparent(high->fromgeom);
11897 				newhigh.fromgeom = high->fromgeom;
11898 				newhigh.fromport = NOPORTPROTO;
11899 				newhigh.frompoint = 0;
11900 				newhigh.fromvar = NOVARIABLE;
11901 				newhigh.fromvarnoeval = NOVARIABLE;
11902 				us_addhighlight(&newhigh);
11903 				us_showallhighlight();
11904 				us_endchanges(NOWINDOWPART);
11905 			}
11906 			continue;
11907 		}
11908 		if (itemHit >= DGIT_LOWICON && itemHit <= DGIT_HIGHICON)
11909 		{
11910 			DiaItemRect(dia, itemHit, &itemRect);
11911 			DiaGetMouse(dia, &x, &y);
11912 			itemHit = (itemHit-DGIT_LOWICON) * 2;
11913 			if (y > (itemRect.top + itemRect.bottom) / 2) itemHit++;
11914 			itemHit = poslist[itemHit].button;
11915 			if (itemHit == DGIT_CORNERBOXED && cantbox) continue;
11916 		}
11917 		for(i=0; i<10; i++) if (itemHit == poslist[i].button)
11918 		{
11919 			for(j=0; j<10; j++) DiaSetControl(dia, poslist[j].button, 0);
11920 			DiaSetControl(dia, itemHit, 1);
11921 			changed = TRUE;
11922 			continue;
11923 		}
11924 		if (itemHit == DGIT_INSIDECELL)
11925 		{
11926 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
11927 			changed = TRUE;
11928 		}
11929 		if (itemHit == DGIT_XOFFSET || itemHit == DGIT_YOFFSET ||
11930 			itemHit == DGIT_LANGUAGE || itemHit == DGIT_WHATTOSHOW ||
11931 			itemHit == DGIT_TEXTFACE || itemHit == DGIT_ROTATION) changed = TRUE;
11932 		if (itemHit == DGIT_TEXTSIZEREL) itemHit = DGIT_TEXTSIZEREL_L;
11933 		if (itemHit == DGIT_TEXTSIZEABS) itemHit = DGIT_TEXTSIZEABS_L;
11934 		if (itemHit == DGIT_TEXTSIZEREL_L || itemHit == DGIT_TEXTSIZEABS_L)
11935 		{
11936 			DiaSetControl(dia, DGIT_TEXTSIZEREL_L, 0);
11937 			DiaSetControl(dia, DGIT_TEXTSIZEABS_L, 0);
11938 			DiaSetControl(dia, itemHit, 1);
11939 			changed = TRUE;
11940 			continue;
11941 		}
11942 		if (itemHit == DGIT_TEXTITALIC || itemHit == DGIT_TEXTBOLD ||
11943 			itemHit == DGIT_TEXTUNDERLINE)
11944 		{
11945 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
11946 			changed = TRUE;
11947 			continue;
11948 		}
11949 	}
11950 
11951 	if (itemHit != CANCEL)
11952 	{
11953 		/* get the new descriptor */
11954 		TDCOPY(newdescript, descript);
11955 		newtype = noevar->type;
11956 		if (changed)
11957 		{
11958 			xcur = atola(DiaGetText(dia, DGIT_XOFFSET), lambda);
11959 			ycur = atola(DiaGetText(dia, DGIT_YOFFSET), lambda);
11960 			if (posnotoffset)
11961 			{
11962 				ni = high->fromgeom->entryaddr.ni;
11963 				us_pushhighlight();
11964 				us_clearhighlightcount();
11965 				startobjectchange((INTBIG)ni, VNODEINST);
11966 				xc = (ni->lowx + ni->highx) / 2;
11967 				yc = (ni->lowy + ni->highy) / 2;
11968 				modifynodeinst(ni, xcur-xc, ycur-yc, xcur-xc, ycur-yc, 0, 0);
11969 				endobjectchange((INTBIG)ni, VNODEINST);
11970 				us_pophighlight(TRUE);
11971 			} else
11972 			{
11973 				us_setdescriptoffset(newdescript, xcur*4/lambda, ycur*4/lambda);
11974 			}
11975 			if (DiaGetControl(dia, DGIT_TEXTSIZEABS_L) != 0)
11976 			{
11977 				j = eatoi(DiaGetText(dia, DGIT_TEXTSIZEABS));
11978 				if (j <= 0) j = 4;
11979 				if (j >= TXTMAXPOINTS) j = TXTMAXPOINTS;
11980 				TDSETSIZE(newdescript, TXTSETPOINTS(j));
11981 			} else
11982 			{
11983 				j = atofr(DiaGetText(dia, DGIT_TEXTSIZEREL)) * 4 / WHOLE;
11984 				if (j <= 0) j = 4;
11985 				if (j >= TXTMAXQLAMBDA) j = TXTMAXQLAMBDA;
11986 				TDSETSIZE(newdescript, TXTSETQLAMBDA(j));
11987 			}
11988 			if (DiaGetControl(dia, DGIT_TEXTITALIC) != 0)
11989 				TDSETITALIC(newdescript, VTITALIC); else
11990 					TDSETITALIC(newdescript, 0);
11991 			if (DiaGetControl(dia, DGIT_TEXTBOLD) != 0)
11992 				TDSETBOLD(newdescript, VTBOLD); else
11993 					TDSETBOLD(newdescript, 0);
11994 			if (DiaGetControl(dia, DGIT_TEXTUNDERLINE) != 0)
11995 				TDSETUNDERLINE(newdescript, VTUNDERLINE); else
11996 					TDSETUNDERLINE(newdescript, 0);
11997 			if (graphicshas(CANCHOOSEFACES))
11998 			{
11999 				i = us_getpopupface(DGIT_TEXTFACE, dia);
12000 				TDSETFACE(newdescript, i);
12001 			}
12002 			i = DiaGetPopupEntry(dia, DGIT_ROTATION);
12003 			TDSETROTATION(newdescript, i);
12004 			for(j=0; j<10; j++)
12005 				if (DiaGetControl(dia, poslist[j].button) != 0) break;
12006 			TDSETPOS(newdescript, poslist[j].value);
12007 			if (DiaGetControl(dia, DGIT_INSIDECELL) != 0)
12008 				TDSETINTERIOR(newdescript, VTINTERIOR); else
12009 					TDSETINTERIOR(newdescript, 0);
12010 			switch (DiaGetPopupEntry(dia, DGIT_WHATTOSHOW))
12011 			{
12012 				case 0: TDSETDISPPART(newdescript, VTDISPLAYVALUE);          break;
12013 				case 1: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALUE);      break;
12014 				case 2: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALINH);     break;
12015 				case 3: TDSETDISPPART(newdescript, VTDISPLAYNAMEVALINHALL);  break;
12016 			}
12017 			newtype &= ~(VCODE1 | VCODE2);
12018 			switch (DiaGetPopupEntry(dia, DGIT_LANGUAGE))
12019 			{
12020 				case 1: newtype |= VTCL;    break;
12021 				case 2: newtype |= VLISP;   break;
12022 				case 3: newtype |= VJAVA;   break;
12023 			}
12024 			i = DiaGetPopupEntry(dia, DGIT_UNITS);
12025 			TDSETUNITS(newdescript, i);
12026 
12027 			/* if this is on a node and the node is rotated, modify grab-point */
12028 			if (high->fromgeom != NOGEOM && high->fromgeom->entryisnode)
12029 			{
12030 				ni = high->fromgeom->entryaddr.ni;
12031 				if (ni->rotation != 0 || ni->transpose != 0)
12032 					us_rotatedescriptI(high->fromgeom, newdescript);
12033 			}
12034 		}
12035 
12036 		/* get the new name */
12037 		newstr = DiaGetText(dia, DGIT_TEXTVALUE);
12038 
12039 		/* see if changes were made */
12040 		if (TDDIFF(newdescript, descript) ||
12041 			 newtype != noevar->type || estrcmp(str, newstr) != 0)
12042 		{
12043 			/* save highlighting */
12044 			us_pushhighlight();
12045 			us_clearhighlightcount();
12046 
12047 			/* set the new descriptor */
12048 			if (high->fromgeom == NOGEOM)
12049 			{
12050 				us_undrawcellvariable(noevar, high->cell);
12051 			} else
12052 			{
12053 				startobjectchange((INTBIG)high->fromgeom->entryaddr.blind, objtype);
12054 			}
12055 
12056 			/* handle changes */
12057 			us_modifytextdescript(high, newdescript);
12058 			if ((newtype&(VISARRAY|VCODE1|VCODE2)) == 0)
12059 			{
12060 				getsimpletype(newstr, &oldtype, &newval, TDGETUNITS(newdescript));
12061 
12062 				/* make sure that node and arc names are strings */
12063 				if (noevar->key == el_node_name_key || noevar->key == el_arc_name_key)
12064 				{
12065 					oldtype = VSTRING;
12066 					newval = (INTBIG)newstr;
12067 				}
12068 				newtype = (newtype & ~VTYPE) | (oldtype & VTYPE);
12069 			} else
12070 			{
12071 				if ((newtype&(VCODE1|VCODE2)) != 0)
12072 				{
12073 					oldtype = VSTRING;
12074 					newtype &= ~VISARRAY;
12075 				} else
12076 				{
12077 					oldtype = newtype & VTYPE;
12078 				}
12079 				switch (oldtype)
12080 				{
12081 					case VINTEGER:
12082 					case VSHORT:
12083 					case VBOOLEAN:
12084 						newval = myatoi(newstr);
12085 						break;
12086 					case VFRACT:
12087 						newval = atofr(newstr);
12088 						break;
12089 					case VSTRING:
12090 						newval = (INTBIG)newstr;
12091 						break;
12092 				}
12093 			}
12094 			if ((newtype&VISARRAY) == 0)
12095 			{
12096 				if (high->fromport != NOPORTPROTO)
12097 				{
12098 					(void)setval((INTBIG)high->fromport, VPORTPROTO,
12099 						makename(noevar->key), newval, newtype);
12100 				} else if (high->fromgeom == NOGEOM)
12101 				{
12102 					(void)setval((INTBIG)high->cell, VNODEPROTO,
12103 						makename(noevar->key), newval, newtype);
12104 				} else
12105 				{
12106 					(void)setval((INTBIG)high->fromgeom->entryaddr.blind, objtype,
12107 						makename(noevar->key), newval, newtype);
12108 				}
12109 			} else
12110 			{
12111 				if (lindex == 0)
12112 				{
12113 					(void)setind((INTBIG)high->fromgeom->entryaddr.blind, objtype,
12114 						makename(noevar->key), 0, newval);
12115 				}
12116 			}
12117 
12118 			/* redisplay the text */
12119 			if (high->fromgeom == NOGEOM)
12120 			{
12121 				us_drawcellvariable(noevar, high->cell);
12122 			} else
12123 			{
12124 				endobjectchange((INTBIG)high->fromgeom->entryaddr.blind, objtype);
12125 			}
12126 			/* restore highlighting */
12127 			us_pophighlight(TRUE);
12128 		}
12129 	}
12130 	DiaDoneDialog(dia);
12131 	if (itemHit == DGIT_EDITTEXT)
12132 	{
12133 		/* save and clear highlighting */
12134 		us_pushhighlight();
12135 		us_clearhighlightcount();
12136 
12137 		/* edit the variable */
12138 		us_editvariabletext(var, objtype,
12139 			(INTBIG)high->fromgeom->entryaddr.blind, makename(var->key));
12140 
12141 		/* restore highlighting */
12142 		us_pophighlight(FALSE);
12143 	}
12144 	if (itemHit == DGIT_OBJECTINFO)
12145 	{
12146 		us_clearhighlightcount();
12147 		newhigh.status = HIGHFROM;
12148 		newhigh.cell = geomparent(high->fromgeom);
12149 		newhigh.fromgeom = high->fromgeom;
12150 		newhigh.fromport = NOPORTPROTO;
12151 		newhigh.frompoint = 0;
12152 		newhigh.fromvar = NOVARIABLE;
12153 		newhigh.fromvarnoeval = NOVARIABLE;
12154 		us_addhighlight(&newhigh);
12155 		us_showallhighlight();
12156 		us_endchanges(NOWINDOWPART);
12157 		if (!high->fromgeom->entryisnode)
12158 		{
12159 			us_getinfoarc(high->fromgeom->entryaddr.ai);
12160 		} else
12161 		{
12162 			us_getinfonode(high->fromgeom->entryaddr.ni, FALSE);
12163 		}
12164 	}
12165 	if (formerstr != 0) efree(formerstr);
12166 }
12167 
12168 /* Port info */
12169 static DIALOGITEM us_portinfodialogitems[] =
12170 {
12171  /*  1 */ {0, {268,376,292,448}, BUTTON, N_("OK")},
12172  /*  2 */ {0, {268,284,292,356}, BUTTON, N_("Cancel")},
12173  /*  3 */ {0, {120,8,136,56}, RADIO, N_("Left")},
12174  /*  4 */ {0, {8,112,24,448}, EDITTEXT, x_("")},
12175  /*  5 */ {0, {88,216,104,264}, EDITTEXT, x_("")},
12176  /*  6 */ {0, {56,8,72,88}, RADIO, N_("Center")},
12177  /*  7 */ {0, {72,8,88,80}, RADIO, N_("Bottom")},
12178  /*  8 */ {0, {88,8,104,56}, RADIO, N_("Top")},
12179  /*  9 */ {0, {104,8,120,64}, RADIO, N_("Right")},
12180  /* 10 */ {0, {136,8,152,104}, RADIO, N_("Lower right")},
12181  /* 11 */ {0, {152,8,168,96}, RADIO, N_("Lower left")},
12182  /* 12 */ {0, {168,8,184,104}, RADIO, N_("Upper right")},
12183  /* 13 */ {0, {184,8,200,96}, RADIO, N_("Upper left")},
12184  /* 14 */ {0, {88,272,104,432}, RADIO, N_("Points (max 63)")},
12185  /* 15 */ {0, {268,192,292,264}, BUTTON, N_("Attributes")},
12186  /* 16 */ {0, {40,16,56,107}, MESSAGE, N_("Text corner:")},
12187  /* 17 */ {0, {208,232,224,296}, EDITTEXT, x_("")},
12188  /* 18 */ {0, {208,384,224,448}, EDITTEXT, x_("")},
12189  /* 19 */ {0, {208,160,224,225}, MESSAGE, N_("X offset:")},
12190  /* 20 */ {0, {208,312,224,377}, MESSAGE, N_("Y offset:")},
12191  /* 21 */ {0, {56,112,88,144}, ICON, (CHAR *)us_icon200},
12192  /* 22 */ {0, {88,112,120,144}, ICON, (CHAR *)us_icon201},
12193  /* 23 */ {0, {120,112,152,144}, ICON, (CHAR *)us_icon202},
12194  /* 24 */ {0, {152,112,184,144}, ICON, (CHAR *)us_icon203},
12195  /* 25 */ {0, {184,112,216,144}, ICON, (CHAR *)us_icon204},
12196  /* 26 */ {0, {8,8,24,104}, MESSAGE, N_("Export name:")},
12197  /* 27 */ {0, {40,280,56,424}, POPUP, x_("")},
12198  /* 28 */ {0, {40,160,56,276}, MESSAGE, N_("Characteristics:")},
12199  /* 29 */ {0, {240,8,256,120}, CHECK, N_("Always drawn")},
12200  /* 30 */ {0, {216,8,232,100}, CHECK, N_("Body only")},
12201  /* 31 */ {0, {112,216,128,264}, EDITTEXT, x_("")},
12202  /* 32 */ {0, {112,272,128,432}, RADIO, N_("Lambda (max 127.75)")},
12203  /* 33 */ {0, {136,248,152,448}, POPUP, x_("")},
12204  /* 34 */ {0, {136,160,152,243}, MESSAGE, N_("Text font:")},
12205  /* 35 */ {0, {184,160,200,231}, CHECK, N_("Italic")},
12206  /* 36 */ {0, {184,256,200,327}, CHECK, N_("Bold")},
12207  /* 37 */ {0, {184,352,200,440}, CHECK, N_("Underline")},
12208  /* 38 */ {0, {100,160,116,208}, MESSAGE, N_("Size")},
12209  /* 39 */ {0, {268,8,292,80}, BUTTON, N_("See Node")},
12210  /* 40 */ {0, {268,100,292,172}, BUTTON, N_("Node Info")},
12211  /* 41 */ {0, {160,248,176,416}, POPUP, x_("")},
12212  /* 42 */ {0, {160,160,176,237}, MESSAGE, N_("Rotation:")},
12213  /* 43 */ {0, {232,160,248,449}, MESSAGE, x_("")},
12214  /* 44 */ {0, {64,160,80,276}, MESSAGE, N_("Reference name:")},
12215  /* 45 */ {0, {64,280,80,448}, EDITTEXT, x_("")}
12216 };
12217 static DIALOG us_portinfodialog = {{50,75,351,534}, N_("Export Information"), 0, 45, us_portinfodialogitems, 0, 0};
12218 
12219 /* special items for the "Export Get Info" dialog: */
12220 #define DGIE_CORNERLEFT        3		/* left (radio) */
12221 #define DGIE_TEXTVALUE         4		/* text name (edit text) */
12222 #define DGIE_ABSTEXTSIZE       5		/* absolute text size (edit text) */
12223 #define DGIE_CORNERCENTER      6		/* center (radio) */
12224 #define DGIE_CORNERBOT         7		/* bottom (radio) */
12225 #define DGIE_CORNERTOP         8		/* top (radio) */
12226 #define DGIE_CORNERRIGHT       9		/* right (radio) */
12227 #define DGIE_CORNERLOWRIGHT   10		/* lower right (radio) */
12228 #define DGIE_CORNERLOWLEFT    11		/* lower left (radio) */
12229 #define DGIE_CORNERUPRIGHT    12		/* upper right (radio) */
12230 #define DGIE_CORNERUPLEFT     13		/* upper left (radio) */
12231 #define DGIE_ABSTEXTSIZE_L    14		/* absolute text size label (radio) */
12232 #define DGIE_ATTRIBUTES       15		/* attributes (button) */
12233 #define DGIE_XOFFSET          17		/* X offset (edit text) */
12234 #define DGIE_YOFFSET          18		/* Y offset (edit text) */
12235 #define DGIE_LOWICON          21		/* first icon (icon) */
12236 #define DGIE_HIGHICON         25		/* last icon (icon) */
12237 #define DGIE_CHARACTERISTICS  27		/* characteristics (popup) */
12238 #define DGIE_ALWAYSDRAWN      29		/* always drawn (check) */
12239 #define DGIE_BODYONLY         30		/* body only (check) */
12240 #define DGIE_RELTEXTSIZE      31		/* relative text size (edit text) */
12241 #define DGIE_RELTEXTSIZE_L    32		/* relative text size label (radio) */
12242 #define DGIE_TEXTFACE         33		/* text face (popup) */
12243 #define DGIE_TEXTFACE_L       34		/* text size label (stat text) */
12244 #define DGIE_TEXTITALIC       35		/* text italic (check) */
12245 #define DGIE_TEXTBOLD         36		/* text italic (check) */
12246 #define DGIE_TEXTUNDERLINE    37		/* text italic (check) */
12247 #define DGIE_SEETHENODE       39		/* see node (button) */
12248 #define DGIE_INFOONNODE       40		/* get info on node (button) */
12249 #define DGIE_ROTATION         41		/* rotation on text (popup) */
12250 #define DGIE_OFFSETREASON     43		/* explanation of offset (stat text) */
12251 #define DGIE_REFNAME_L        44		/* reference name label (stat text) */
12252 #define DGIE_REFNAME          45		/* reference name (edit text) */
12253 
us_getinfoexport(HIGHLIGHT * high)12254 void us_getinfoexport(HIGHLIGHT *high)
12255 {
12256 	INTBIG itemHit, j, i, lambda, xcur, ycur, height;
12257 	UINTBIG newbit;
12258 	BOOLEAN changed;
12259 	UINTBIG descript[TEXTDESCRIPTSIZE], newdescript[TEXTDESCRIPTSIZE];
12260 	INTBIG x, y;
12261 	CHAR *str, *pt, *newstr, *refname, *newlang[NUMPORTCHARS], buf[80];
12262 	RECTAREA itemRect;
12263 	REGISTER PORTPROTO *pp;
12264 	REGISTER NODEINST *ni;
12265 	REGISTER NODEPROTO *cell;
12266 	REGISTER LIBRARY *lib;
12267 	REGISTER TECHNOLOGY *tech;
12268 	REGISTER VARIABLE *var;
12269 	HIGHLIGHT newhigh;
12270 	REGISTER void *dia;
12271 	static struct butlist poslist[9] =
12272 	{
12273 		{VTPOSCENT,      DGIE_CORNERCENTER},
12274 		{VTPOSUP,        DGIE_CORNERBOT},
12275 		{VTPOSDOWN,      DGIE_CORNERTOP},
12276 		{VTPOSLEFT,      DGIE_CORNERRIGHT},
12277 		{VTPOSRIGHT,     DGIE_CORNERLEFT},
12278 		{VTPOSUPLEFT,    DGIE_CORNERLOWRIGHT},
12279 		{VTPOSUPRIGHT,   DGIE_CORNERLOWLEFT},
12280 		{VTPOSDOWNLEFT,  DGIE_CORNERUPRIGHT},
12281 		{VTPOSDOWNRIGHT, DGIE_CORNERUPLEFT}
12282 	};
12283 
12284 	/* display the port dialog box */
12285 	dia = DiaInitDialog(&us_portinfodialog);
12286 	if (dia == 0) return;
12287 	for(i=0; i<NUMPORTCHARS; i++) newlang[i] = TRANSLATE(us_exportcharnames[i]);
12288 	DiaSetPopup(dia, DGIE_CHARACTERISTICS, NUMPORTCHARS, newlang);
12289 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_rotationtypes[i]);
12290 	DiaSetPopup(dia, DGIE_ROTATION, 4, newlang);
12291 
12292 	/* get information about the export */
12293 	tech = us_hightech(high);
12294 	cell = us_highcell(high);
12295 	if (cell == NONODEPROTO) lib = el_curlib; else
12296 		lib = cell->lib;
12297 	lambda = lib->lambda[tech->techindex];
12298 	pp = high->fromport;
12299 	ni = high->fromgeom->entryaddr.ni;
12300 	str = pp->protoname;
12301 	TDCOPY(descript, pp->textdescript);
12302 	if (ni->rotation != 0 || ni->transpose != 0)
12303 		us_rotatedescript(ni->geom, descript);
12304 
12305 	/* set port information */
12306 	DiaSetText(dia, -DGIE_TEXTVALUE, str);
12307 	if ((pp->userbits&PORTDRAWN) != 0) DiaSetControl(dia, DGIE_ALWAYSDRAWN, 1);
12308 	if ((pp->userbits&BODYONLY) != 0) DiaSetControl(dia, DGIE_BODYONLY, 1);
12309 
12310 	/* set the export characteristics button */
12311 	for(i=0; i<NUMPORTCHARS; i++)
12312 		if (us_exportcharlist[i] == (pp->userbits&STATEBITS))
12313 	{
12314 		DiaSetPopupEntry(dia, DGIE_CHARACTERISTICS, i);
12315 		break;
12316 	}
12317 
12318 	/* set reference name */
12319 	var = getval((INTBIG)pp, VPORTPROTO, VSTRING, x_("EXPORT_reference_name"));
12320 	if (var == NOVARIABLE) refname = x_(""); else
12321 	{
12322 		refname = (CHAR *)var->addr;
12323 		DiaSetText(dia, DGIE_REFNAME, refname);
12324 	}
12325 	if ((pp->userbits&STATEBITS) == REFOUTPORT || (pp->userbits&STATEBITS) == REFINPORT ||
12326 		(pp->userbits&STATEBITS) == REFBASEPORT)
12327 	{
12328 		DiaUnDimItem(dia, DGIE_REFNAME_L);
12329 		DiaUnDimItem(dia, DGIE_REFNAME);
12330 	} else
12331 	{
12332 		DiaDimItem(dia, DGIE_REFNAME_L);
12333 		DiaDimItem(dia, DGIE_REFNAME);
12334 	}
12335 
12336 	/* set the orientation button */
12337 	for(i=0; i<9; i++)
12338 		if (poslist[i].value == TDGETPOS(descript))
12339 	{
12340 		DiaSetControl(dia, poslist[i].button, 1);
12341 		break;
12342 	}
12343 
12344 	/* set the size information */
12345 	i = TDGETSIZE(descript);
12346 	if (TXTGETPOINTS(i) != 0)
12347 	{
12348 		/* show point size */
12349 		esnprintf(buf, 30, x_("%ld"), TXTGETPOINTS(i));
12350 		DiaSetText(dia, DGIE_ABSTEXTSIZE, buf);
12351 		DiaSetControl(dia, DGIE_ABSTEXTSIZE_L, 1);
12352 
12353 		/* figure out how many lambda the point value is */
12354 		height = TXTGETPOINTS(i);
12355 		if (el_curwindowpart != NOWINDOWPART)
12356 			height = roundfloat((float)height / el_curwindowpart->scaley);
12357 		height = height * 4 / lambda;
12358 		DiaSetText(dia, DGIE_RELTEXTSIZE, frtoa(height * WHOLE / 4));
12359 	} else if (TXTGETQLAMBDA(i) != 0)
12360 	{
12361 		/* show lambda value */
12362 		height = TXTGETQLAMBDA(i);
12363 		DiaSetText(dia, DGIE_RELTEXTSIZE, frtoa(height * WHOLE / 4));
12364 		DiaSetControl(dia, DGIE_RELTEXTSIZE_L, 1);
12365 
12366 		/* figure out how many points the lambda value is */
12367 		height = height * lambda / 4;
12368 		if (el_curwindowpart != NOWINDOWPART)
12369 			height = applyyscale(el_curwindowpart, height);
12370 		esnprintf(buf, 30, x_("%ld"), height);
12371 		DiaSetText(dia, DGIE_ABSTEXTSIZE, buf);
12372 	}
12373 	if (graphicshas(CANCHOOSEFACES))
12374 	{
12375 		DiaUnDimItem(dia, DGIE_TEXTFACE_L);
12376 		us_setpopupface(DGIE_TEXTFACE, TDGETFACE(descript), TRUE, dia);
12377 	} else
12378 	{
12379 		DiaDimItem(dia, DGIE_TEXTFACE_L);
12380 	}
12381 	j = TDGETROTATION(descript);
12382 	DiaSetPopupEntry(dia, DGIE_ROTATION, j);
12383 	if (graphicshas(CANMODIFYFONTS))
12384 	{
12385 		DiaUnDimItem(dia, DGIE_TEXTITALIC);
12386 		DiaUnDimItem(dia, DGIE_TEXTBOLD);
12387 		DiaUnDimItem(dia, DGIE_TEXTUNDERLINE);
12388 		if (TDGETITALIC(descript) != 0) DiaSetControl(dia, DGIE_TEXTITALIC, 1);
12389 		if (TDGETBOLD(descript) != 0) DiaSetControl(dia, DGIE_TEXTBOLD, 1);
12390 		if (TDGETUNDERLINE(descript) != 0) DiaSetControl(dia, DGIE_TEXTUNDERLINE, 1);
12391 	} else
12392 	{
12393 		DiaDimItem(dia, DGIE_TEXTITALIC);
12394 		DiaDimItem(dia, DGIE_TEXTBOLD);
12395 		DiaDimItem(dia, DGIE_TEXTUNDERLINE);
12396 	}
12397 
12398 	/* set offsets */
12399 	i = TDGETXOFF(descript);
12400 	DiaSetText(dia, DGIE_XOFFSET, latoa(i * lambda / 4, lambda));
12401 	j = TDGETYOFF(descript);
12402 	DiaSetText(dia, DGIE_YOFFSET, latoa(j * lambda / 4, lambda));
12403 	esnprintf(buf, 80, "Offset in increments of %s",
12404 		latoa((TDGETOFFSCALE(descript)+1) * lambda / 4, lambda));
12405 	DiaSetText(dia, DGIE_OFFSETREASON, buf);
12406 	if (i == 0 && j == 0 && ni->proto == gen_invispinprim)
12407 	{
12408 		DiaDimItem(dia, DGIE_XOFFSET);
12409 		DiaDimItem(dia, DGIE_YOFFSET);
12410 	} else
12411 	{
12412 		DiaUnDimItem(dia, DGIE_XOFFSET);
12413 		DiaUnDimItem(dia, DGIE_YOFFSET);
12414 	}
12415 
12416 	/* loop until done */
12417 	changed = FALSE;
12418 	for(;;)
12419 	{
12420 		itemHit = DiaNextHit(dia);
12421 		if (itemHit == CANCEL) break;
12422 		if (itemHit == OK || itemHit == DGIE_ATTRIBUTES || itemHit == DGIE_INFOONNODE)
12423 		{
12424 			/* do not allow empty export names */
12425 			pt = DiaGetText(dia, DGIE_TEXTVALUE);
12426 			while (*pt == ' ' || *pt == '\t') pt++;
12427 			if (*pt == 0)
12428 			{
12429 				DiaMessageInDialog(_("Must have a non-empty export name"));
12430 				continue;
12431 			}
12432 			break;
12433 		}
12434 		if (itemHit == DGIE_SEETHENODE)
12435 		{
12436 			us_clearhighlightcount();
12437 			newhigh.status = HIGHFROM;
12438 			newhigh.cell = ni->parent;
12439 			newhigh.fromgeom = ni->geom;
12440 			newhigh.fromport = pp->subportproto;
12441 			newhigh.frompoint = 0;
12442 			newhigh.fromvar = NOVARIABLE;
12443 			newhigh.fromvarnoeval = NOVARIABLE;
12444 			us_addhighlight(&newhigh);
12445 			us_showallhighlight();
12446 			us_endchanges(NOWINDOWPART);
12447 			continue;
12448 		}
12449 		if (itemHit >= DGIE_LOWICON && itemHit <= DGIE_HIGHICON)
12450 		{
12451 			DiaItemRect(dia, itemHit, &itemRect);
12452 			DiaGetMouse(dia, &x, &y);
12453 			itemHit = (itemHit-DGIE_LOWICON) * 2;
12454 			if (y > (itemRect.top + itemRect.bottom) / 2) itemHit++;
12455 			if (itemHit == 9) continue;
12456 			itemHit = poslist[itemHit].button;
12457 		}
12458 		for(i=0; i<9; i++) if (itemHit == poslist[i].button)
12459 		{
12460 			for(j=0; j<9; j++) DiaSetControl(dia, poslist[j].button, 0);
12461 			DiaSetControl(dia, itemHit, 1);
12462 			changed = TRUE;
12463 			continue;
12464 		}
12465 		if (itemHit == DGIE_ALWAYSDRAWN || itemHit == DGIE_BODYONLY)
12466 		{
12467 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
12468 			changed = TRUE;
12469 		}
12470 		if (itemHit == DGIE_TEXTFACE || itemHit == DGIE_XOFFSET ||
12471 			itemHit == DGIE_YOFFSET || itemHit == DGIE_CHARACTERISTICS ||
12472 			itemHit == DGIE_ROTATION) changed = TRUE;
12473 		if (itemHit == DGIE_RELTEXTSIZE) itemHit = DGIE_RELTEXTSIZE_L;
12474 		if (itemHit == DGIE_ABSTEXTSIZE) itemHit = DGIE_ABSTEXTSIZE_L;
12475 		if (itemHit == DGIE_RELTEXTSIZE_L || itemHit == DGIE_ABSTEXTSIZE_L)
12476 		{
12477 			DiaSetControl(dia, DGIE_RELTEXTSIZE_L, 0);
12478 			DiaSetControl(dia, DGIE_ABSTEXTSIZE_L, 0);
12479 			DiaSetControl(dia, itemHit, 1);
12480 			changed = TRUE;
12481 			continue;
12482 		}
12483 		if (itemHit == DGIE_TEXTITALIC || itemHit == DGIE_TEXTBOLD ||
12484 			itemHit == DGIE_TEXTUNDERLINE)
12485 		{
12486 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
12487 			changed = TRUE;
12488 			continue;
12489 		}
12490 		if (itemHit == DGIE_CHARACTERISTICS)
12491 		{
12492 			i = DiaGetPopupEntry(dia, DGIE_CHARACTERISTICS);
12493 			newbit = us_exportcharlist[i];
12494 			if (newbit == REFOUTPORT || newbit == REFINPORT || newbit == REFBASEPORT)
12495 			{
12496 				DiaUnDimItem(dia, DGIE_REFNAME_L);
12497 				DiaUnDimItem(dia, DGIE_REFNAME);
12498 			} else
12499 			{
12500 				DiaDimItem(dia, DGIE_REFNAME_L);
12501 				DiaDimItem(dia, DGIE_REFNAME);
12502 			}
12503 			continue;
12504 		}
12505 	}
12506 	if (itemHit != CANCEL)
12507 	{
12508 		/* get new port characteristics if applicable */
12509 		if (changed)
12510 		{
12511 			newbit = pp->userbits;
12512 			i = DiaGetPopupEntry(dia, DGIE_CHARACTERISTICS);
12513 			newbit = (newbit & ~STATEBITS) | us_exportcharlist[i];
12514 			if (DiaGetControl(dia, DGIE_ALWAYSDRAWN) == 0) newbit &= ~PORTDRAWN; else
12515 				newbit |= PORTDRAWN;
12516 			if (DiaGetControl(dia, DGIE_BODYONLY) == 0) newbit &= ~BODYONLY; else
12517 				newbit |= BODYONLY;
12518 			if (newbit != pp->userbits)
12519 			{
12520 				setval((INTBIG)pp, VPORTPROTO, x_("userbits"), newbit, VINTEGER);
12521 				changeallports(pp);
12522 			}
12523 		}
12524 		newstr = DiaGetText(dia, DGIE_REFNAME);
12525 		while (*newstr == ' ') newstr++;
12526 		if (estrcmp(refname, newstr) != 0)
12527 		{
12528 			if (*newstr == 0)
12529 			{
12530 				if (getval((INTBIG)pp, VPORTPROTO, VSTRING, x_("EXPORT_reference_name")) != NOVARIABLE)
12531 					delval((INTBIG)pp, VPORTPROTO, x_("EXPORT_reference_name"));
12532 			} else
12533 			{
12534 				setval((INTBIG)pp, VPORTPROTO, x_("EXPORT_reference_name"),
12535 					(INTBIG)newstr, VSTRING);
12536 			}
12537 		}
12538 
12539 		/* get the new descriptor */
12540 		TDCOPY(newdescript, descript);
12541 		if (changed)
12542 		{
12543 			xcur = atola(DiaGetText(dia, DGIE_XOFFSET), 0);
12544 			ycur = atola(DiaGetText(dia, DGIE_YOFFSET), 0);
12545 			us_setdescriptoffset(newdescript, xcur*4/lambda, ycur*4/lambda);
12546 			if (DiaGetControl(dia, DGIE_ABSTEXTSIZE_L) != 0)
12547 			{
12548 				j = eatoi(DiaGetText(dia, DGIE_ABSTEXTSIZE));
12549 				if (j <= 0) j = 4;
12550 				if (j >= TXTMAXPOINTS) j = TXTMAXPOINTS;
12551 				TDSETSIZE(newdescript, TXTSETPOINTS(j));
12552 			} else
12553 			{
12554 				j = atofr(DiaGetText(dia, DGIE_RELTEXTSIZE)) * 4 / WHOLE;
12555 				if (j <= 0) j = 4;
12556 				if (j >= TXTMAXQLAMBDA) j = TXTMAXQLAMBDA;
12557 				TDSETSIZE(newdescript, TXTSETQLAMBDA(j));
12558 			}
12559 			if (DiaGetControl(dia, DGIE_TEXTITALIC) != 0)
12560 				TDSETITALIC(newdescript, VTITALIC); else
12561 					TDSETITALIC(newdescript, 0);
12562 			if (DiaGetControl(dia, DGIE_TEXTBOLD) != 0)
12563 				TDSETBOLD(newdescript, VTBOLD); else
12564 					TDSETBOLD(newdescript, 0);
12565 			if (DiaGetControl(dia, DGIE_TEXTUNDERLINE) != 0)
12566 				TDSETUNDERLINE(newdescript, VTUNDERLINE); else
12567 					TDSETUNDERLINE(newdescript, 0);
12568 			if (graphicshas(CANCHOOSEFACES))
12569 			{
12570 				i = us_getpopupface(DGIE_TEXTFACE, dia);
12571 				TDSETFACE(newdescript, i);
12572 			}
12573 			j = DiaGetPopupEntry(dia, DGIE_ROTATION);
12574 			TDSETROTATION(newdescript, j);
12575 			for(j=0; j<9; j++)
12576 				if (DiaGetControl(dia, poslist[j].button) != 0) break;
12577 			TDSETPOS(newdescript, poslist[j].value);
12578 
12579 			/* if this node is rotated, modify grab-point */
12580 			if (ni->rotation != 0 || ni->transpose != 0)
12581 				us_rotatedescriptI(high->fromgeom, newdescript);
12582 		}
12583 
12584 		/* get the new name */
12585 		newstr = DiaGetText(dia, DGIE_TEXTVALUE);
12586 
12587 		/* see if changes were made */
12588 		if (TDDIFF(newdescript, descript) || estrcmp(str, newstr) != 0)
12589 		{
12590 			/* save highlighting */
12591 			us_pushhighlight();
12592 			us_clearhighlightcount();
12593 
12594 			/* handle changes */
12595 			startobjectchange((INTBIG)high->fromgeom->entryaddr.blind, VNODEINST);
12596 			if (TDDIFF(newdescript, descript))
12597 				us_modifytextdescript(high, newdescript);
12598 			if (estrcmp(str, newstr) != 0) us_renameport(pp, newstr);
12599 			endobjectchange((INTBIG)high->fromgeom->entryaddr.blind, VNODEINST);
12600 
12601 			/* restore highlighting */
12602 			us_pophighlight(TRUE);
12603 		}
12604 	}
12605 	DiaDoneDialog(dia);
12606 	if (itemHit == DGIE_INFOONNODE)
12607 	{
12608 		us_clearhighlightcount();
12609 		newhigh.status = HIGHFROM;
12610 		newhigh.cell = ni->parent;
12611 		newhigh.fromgeom = ni->geom;
12612 		newhigh.fromport = pp->subportproto;
12613 		newhigh.frompoint = 0;
12614 		newhigh.fromvar = NOVARIABLE;
12615 		newhigh.fromvarnoeval = NOVARIABLE;
12616 		us_addhighlight(&newhigh);
12617 		us_showallhighlight();
12618 		us_endchanges(NOWINDOWPART);
12619 		us_getinfonode(ni, FALSE);
12620 		return;
12621 	}
12622 	if (itemHit == DGIE_ATTRIBUTES)
12623 		(void)us_attributesdlog();
12624 }
12625 
12626 /* Arc info */
12627 static DIALOGITEM us_showarcdialogitems[] =
12628 {
12629  /*  1 */ {0, {148,336,172,408}, BUTTON, N_("OK")},
12630  /*  2 */ {0, {108,336,132,408}, BUTTON, N_("Cancel")},
12631  /*  3 */ {0, {188,336,212,408}, BUTTON, N_("Attributes")},
12632  /*  4 */ {0, {104,88,120,176}, MESSAGE, x_("")},
12633  /*  5 */ {0, {8,88,24,392}, MESSAGE, x_("")},
12634  /*  6 */ {0, {32,88,48,392}, MESSAGE, x_("")},
12635  /*  7 */ {0, {56,88,72,392}, EDITTEXT, x_("")},
12636  /*  8 */ {0, {80,88,96,172}, EDITTEXT, x_("")},
12637  /*  9 */ {0, {128,88,144,320}, MESSAGE, x_("")},
12638  /* 10 */ {0, {80,280,96,364}, MESSAGE, x_("")},
12639  /* 11 */ {0, {176,88,192,320}, MESSAGE, x_("")},
12640  /* 12 */ {0, {8,16,24,80}, MESSAGE, N_("Type:")},
12641  /* 13 */ {0, {32,16,48,80}, MESSAGE, N_("Network:")},
12642  /* 14 */ {0, {80,16,96,80}, MESSAGE, N_("Width:")},
12643  /* 15 */ {0, {104,16,120,80}, MESSAGE, N_("Angle:")},
12644  /* 16 */ {0, {128,16,144,80}, MESSAGE, N_("Head:")},
12645  /* 17 */ {0, {80,216,96,280}, MESSAGE, N_("Bus size:")},
12646  /* 18 */ {0, {176,16,192,80}, MESSAGE, N_("Tail:")},
12647  /* 19 */ {0, {104,196,120,324}, CHECK, N_("Easy to Select")},
12648  /* 20 */ {0, {252,16,268,112}, CHECK, N_("Negated")},
12649  /* 21 */ {0, {276,16,292,112}, CHECK, N_("Directional")},
12650  /* 22 */ {0, {300,16,316,120}, CHECK, N_("Ends extend")},
12651  /* 23 */ {0, {252,136,268,240}, CHECK, N_("Ignore head")},
12652  /* 24 */ {0, {276,136,292,232}, CHECK, N_("Ignore tail")},
12653  /* 25 */ {0, {300,136,316,304}, CHECK, N_("Reverse head and tail")},
12654  /* 26 */ {0, {252,328,268,424}, CHECK, N_("Temporary")},
12655  /* 27 */ {0, {276,312,292,416}, CHECK, N_("Fixed-angle")},
12656  /* 28 */ {0, {56,16,72,80}, MESSAGE, N_("Name:")},
12657  /* 29 */ {0, {228,136,244,300}, MESSAGE, x_("")},
12658  /* 30 */ {0, {152,40,168,80}, MESSAGE, N_("At:")},
12659  /* 31 */ {0, {152,88,168,220}, MESSAGE, x_("")},
12660  /* 32 */ {0, {152,232,168,272}, BUTTON, N_("See")},
12661  /* 33 */ {0, {200,40,216,80}, MESSAGE, N_("At:")},
12662  /* 34 */ {0, {200,88,216,220}, MESSAGE, x_("")},
12663  /* 35 */ {0, {200,232,216,272}, BUTTON, N_("See")},
12664  /* 36 */ {0, {152,280,168,320}, BUTTON, N_("Info")},
12665  /* 37 */ {0, {200,280,216,320}, BUTTON, N_("Info")},
12666  /* 38 */ {0, {300,312,316,416}, CHECK, N_("Slidable")},
12667  /* 39 */ {0, {228,312,244,404}, CHECK, N_("Rigid")},
12668  /* 40 */ {0, {228,16,244,132}, MESSAGE, x_("")}
12669 };
12670 static DIALOG us_showarcdialog = {{50,75,375,509}, N_("Arc Information"), 0, 40, us_showarcdialogitems, 0, 0};
12671 
12672 /* special items for the "Arc Get Info" dialog: */
12673 #define DGIA_ATTRIBUTES    3		/* attributes (button) */
12674 #define DGIA_ANGLE         4		/* angle (stat text) */
12675 #define DGIA_TYPE          5		/* type (stat text) */
12676 #define DGIA_NETWORK       6		/* network (stat text) */
12677 #define DGIA_NAME          7		/* name (edit text) */
12678 #define DGIA_WIDTH         8		/* width (edit text) */
12679 #define DGIA_NODEHEAD      9		/* head node (stat text) */
12680 #define DGIA_BUSSIZE      10		/* bus size (stat text) */
12681 #define DGIA_NODETAIL     11		/* tail node (stat text) */
12682 #define DGIA_EASYSELECT   19		/* easy to select (check) */
12683 #define DGIA_NEGATED      20		/* negated (check) */
12684 #define DGIA_DIRECTIONAL  21		/* directional (check) */
12685 #define DGIA_ENDEXTEND    22		/* ends extend (check) */
12686 #define DGIA_IGNOREHEAD   23		/* ignore head (check) */
12687 #define DGIA_IGNORETAIL   24		/* ignore tail (check) */
12688 #define DGIA_REVERSE      25		/* reverse (check) */
12689 #define DGIA_TEMPORARY    26		/* temporarily (check) */
12690 #define DGIA_FIXANGLE     27		/* fixed-angle (check) */
12691 #define DGIA_EXTRAINFO    29		/* extra information (stat text) */
12692 #define DGIA_HEADPOS      31		/* head coordinate (stat text) */
12693 #define DGIA_SEEHEAD      32		/* see head (button) */
12694 #define DGIA_TAILPOS      34		/* tail coordinate (stat text) */
12695 #define DGIA_SEETAIL      35		/* see tail (button) */
12696 #define DGIA_HEADINFO     36		/* head info (button) */
12697 #define DGIA_TAILINFO     37		/* tail info (button) */
12698 #define DGIA_SLIDABLE     38		/* slidable (check) */
12699 #define DGIA_RIGID        39		/* rigid (check) */
12700 #define DGIA_EXTRAINFO_L  40		/* extra information label (stat text) */
12701 
us_getinfoarc(ARCINST * ai)12702 void us_getinfoarc(ARCINST *ai)
12703 {
12704 	INTBIG itemHit, rigstate, oldrigstate, lambda;
12705 	BOOLEAN changed;
12706 	CHAR ent[50], *str, *newstr, *newlang[30], *colorname, *colorsymbol;
12707 	INTBIG i, wid, oldwid, end;
12708 	REGISTER VARIABLE *var;
12709 	HIGHLIGHT high;
12710 	REGISTER void *dia;
12711 
12712 	/* artwork arcs have a color popup */
12713 	if (ai->proto->tech == art_tech) us_showarcdialogitems[DGIA_EXTRAINFO-1].type = POPUP; else
12714 		us_showarcdialogitems[DGIA_EXTRAINFO-1].type = MESSAGE;
12715 
12716 	/* show the dialog */
12717 	dia = DiaInitDialog(&us_showarcdialog);
12718 	if (dia == 0) return;
12719 
12720 	/* enable everything */
12721 	DiaUnDimItem(dia, DGIA_RIGID);
12722 	DiaUnDimItem(dia, DGIA_FIXANGLE);
12723 	DiaUnDimItem(dia, DGIA_NAME);
12724 	DiaUnDimItem(dia, DGIA_ANGLE);
12725 	DiaUnDimItem(dia, DGIA_SLIDABLE);
12726 	DiaUnDimItem(dia, DGIA_NEGATED);
12727 	DiaUnDimItem(dia, DGIA_DIRECTIONAL);
12728 	DiaUnDimItem(dia, DGIA_ENDEXTEND);
12729 	DiaUnDimItem(dia, DGIA_IGNOREHEAD);
12730 	DiaUnDimItem(dia, DGIA_IGNORETAIL);
12731 	DiaUnDimItem(dia, DGIA_REVERSE);
12732 	DiaUnDimItem(dia, DGIA_TEMPORARY);
12733 	DiaUnDimItem(dia, DGIA_WIDTH);
12734 	DiaUnDimItem(dia, DGIA_EASYSELECT);
12735 	DiaUnDimItem(dia, DGIA_EXTRAINFO);
12736 
12737 	/* set prototype name */
12738 	DiaSetText(dia, DGIA_TYPE, ai->proto->protoname);
12739 
12740 	/* load the network and arc names if any */
12741 	var = getvalkey((INTBIG)ai, VARCINST, VSTRING, el_arc_name_key);
12742 	if (var != NOVARIABLE)
12743 	{
12744 		str = (CHAR *)var->addr;
12745 		DiaSetText(dia, -DGIA_NAME, str);
12746 	} else str = x_("");
12747 	if (ai->network != NONETWORK)
12748 		DiaSetText(dia, DGIA_NETWORK, describenetwork(ai->network)); else
12749 			DiaSetText(dia, DGIA_NETWORK, _("*** NONE ***"));
12750 
12751 	/* load the width */
12752 	lambda = lambdaofarc(ai);
12753 	oldwid = ai->width - arcwidthoffset(ai);
12754 	DiaSetText(dia, DGIA_WIDTH, latoa(oldwid, lambda));
12755 
12756 	/* load the position */
12757 	(void)esnprintf(ent, 50, x_("(%s,%s)"), latoa(ai->end[1].xpos, lambda), latoa(ai->end[1].ypos, lambda));
12758 	DiaSetText(dia, DGIA_HEADPOS, ent);
12759 	DiaSetText(dia, DGIA_NODEHEAD, describenodeinst(ai->end[1].nodeinst));
12760 	(void)esnprintf(ent, 50, x_("(%s,%s)"), latoa(ai->end[0].xpos, lambda), latoa(ai->end[0].ypos, lambda));
12761 	DiaSetText(dia, DGIA_TAILPOS, ent);
12762 	DiaSetText(dia, DGIA_NODETAIL, describenodeinst(ai->end[0].nodeinst));
12763 
12764 	/* load angle */
12765 	(void)esnprintf(ent, 50, x_(" %ld"), (ai->userbits&AANGLE) >> AANGLESH);
12766 	DiaSetText(dia, DGIA_ANGLE, ent);
12767 
12768 	/* load the selectability factor */
12769 	if ((ai->userbits&HARDSELECTA) == 0) DiaSetControl(dia, DGIA_EASYSELECT, 1);
12770 
12771 	/* load bus width if any */
12772 	if (ai->network != NONETWORK && ai->network->buswidth > 1)
12773 	{
12774 		(void)esnprintf(ent, 50, x_(" %d"), ai->network->buswidth);
12775 		DiaSetText(dia, DGIA_BUSSIZE, ent);
12776 	} else DiaSetText(dia, DGIA_BUSSIZE, _("N/A"));
12777 
12778 	/* set the constraint buttons */
12779 	if (el_curconstraint == cla_constraint)
12780 	{
12781 		oldrigstate = 1;
12782 		if (((ai->userbits&FIXED) == 0 || ai->changed == cla_changeclock+3) &&
12783 			ai->changed != cla_changeclock+2)
12784 		{
12785 			if (ai->changed == cla_changeclock+3) oldrigstate = 3;
12786 		} else
12787 		{
12788 			if (ai->changed == cla_changeclock+2) oldrigstate = 2; else
12789 				oldrigstate = 0;
12790 		}
12791 		switch (oldrigstate)
12792 		{
12793 			case 0:
12794 				DiaSetControl(dia, DGIA_RIGID, 1);
12795 				break;
12796 			case 1:
12797 				break;
12798 			case 2:
12799 				DiaSetControl(dia, DGIA_RIGID, 1);
12800 				/* FALLTHROUGH */
12801 			case 3:
12802 				DiaSetControl(dia, DGIA_TEMPORARY, 1);
12803 				break;
12804 		}
12805 		if ((ai->userbits&FIXANG) != 0) DiaSetControl(dia, DGIA_FIXANGLE, 1);
12806 		if ((ai->userbits&CANTSLIDE) == 0) DiaSetControl(dia, DGIA_SLIDABLE, 1);
12807 	} else
12808 	{
12809 		DiaDimItem(dia, DGIA_RIGID);
12810 		DiaDimItem(dia, DGIA_FIXANGLE);
12811 		DiaDimItem(dia, DGIA_SLIDABLE);
12812 		DiaDimItem(dia, DGIA_TEMPORARY);
12813 		newstr = (CHAR *)(*(el_curconstraint->request))(x_("describearc"), (INTBIG)ai);
12814 		if (*newstr != 0)
12815 		{
12816 			DiaSetText(dia, DGIA_EXTRAINFO, newstr);
12817 			DiaSetText(dia, DGIA_EXTRAINFO_L, _("Constraint:"));
12818 		}
12819 	}
12820 	if ((ai->userbits&ISNEGATED) != 0) DiaSetControl(dia, DGIA_NEGATED, 1);
12821 	if ((ai->userbits&ISDIRECTIONAL) != 0) DiaSetControl(dia, DGIA_DIRECTIONAL, 1);
12822 	if ((ai->userbits&NOEXTEND) == 0) DiaSetControl(dia, DGIA_ENDEXTEND, 1);
12823 	if ((ai->userbits&NOTEND1) != 0) DiaSetControl(dia, DGIA_IGNOREHEAD, 1);
12824 	if ((ai->userbits&NOTEND0) != 0) DiaSetControl(dia, DGIA_IGNORETAIL, 1);
12825 	if ((ai->userbits&REVERSEEND) != 0) DiaSetControl(dia, DGIA_REVERSE, 1);
12826 
12827 	/* show color choices if artwork */
12828 	if (ai->proto->tech == art_tech)
12829 	{
12830 		DiaSetText(dia, DGIA_EXTRAINFO_L, _("Color:"));
12831 		for(i=0; i<25; i++)
12832 		{
12833 			(void)ecolorname(us_colorvaluelist[i], &colorname, &colorsymbol);
12834 			newlang[i] = TRANSLATE(colorname);
12835 		}
12836 		DiaSetPopup(dia, DGIA_EXTRAINFO, 25, newlang);
12837 		var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, art_colorkey);
12838 		if (var == NOVARIABLE) i = 6; else
12839 		{
12840 			for(i=0; i<25; i++) if (us_colorvaluelist[i] == var->addr) break;
12841 		}
12842 		DiaSetPopupEntry(dia, DGIA_EXTRAINFO, i);
12843 	}
12844 
12845 	/* if the arc can't be edited, disable all changes */
12846 	if (us_cantedit(ai->parent, NONODEINST, FALSE))
12847 	{
12848 		DiaDimItem(dia, DGIA_RIGID);
12849 		DiaDimItem(dia, DGIA_FIXANGLE);
12850 		DiaDimItem(dia, DGIA_NAME);
12851 		DiaDimItem(dia, DGIA_ANGLE);
12852 		DiaDimItem(dia, DGIA_SLIDABLE);
12853 		DiaDimItem(dia, DGIA_NEGATED);
12854 		DiaDimItem(dia, DGIA_DIRECTIONAL);
12855 		DiaDimItem(dia, DGIA_ENDEXTEND);
12856 		DiaDimItem(dia, DGIA_IGNOREHEAD);
12857 		DiaDimItem(dia, DGIA_IGNORETAIL);
12858 		DiaDimItem(dia, DGIA_REVERSE);
12859 		DiaDimItem(dia, DGIA_TEMPORARY);
12860 		DiaDimItem(dia, DGIA_WIDTH);
12861 		DiaDimItem(dia, DGIA_EASYSELECT);
12862 		DiaDimItem(dia, DGIA_EXTRAINFO);
12863 	}
12864 
12865 	/* loop until done */
12866 	changed = FALSE;
12867 	for(;;)
12868 	{
12869 		itemHit = DiaNextHit(dia);
12870 		if (itemHit == OK || itemHit == CANCEL ||
12871 			itemHit == DGIA_HEADINFO || itemHit == DGIA_TAILINFO ||
12872 			itemHit == DGIA_ATTRIBUTES) break;
12873 		if (itemHit == DGIA_RIGID || itemHit == DGIA_FIXANGLE ||
12874 			itemHit == DGIA_SLIDABLE || itemHit == DGIA_NEGATED ||
12875 			itemHit == DGIA_DIRECTIONAL || itemHit == DGIA_ENDEXTEND ||
12876 			itemHit == DGIA_IGNOREHEAD || itemHit == DGIA_IGNORETAIL ||
12877 			itemHit == DGIA_REVERSE || itemHit == DGIA_TEMPORARY ||
12878 			itemHit == DGIA_EASYSELECT)
12879 		{
12880 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
12881 			changed = TRUE;
12882 			continue;
12883 		}
12884 		if (itemHit == DGIA_EXTRAINFO)
12885 		{
12886 			if (ai->proto->tech == art_tech) changed = TRUE;
12887 			continue;
12888 		}
12889 		if (itemHit == DGIA_NAME || itemHit == DGIA_WIDTH)
12890 		{
12891 			changed = TRUE;
12892 			continue;
12893 		}
12894 		if (itemHit == DGIA_SEEHEAD || itemHit == DGIA_SEETAIL)
12895 		{
12896 			/* highlight an end */
12897 			if (itemHit == DGIA_SEEHEAD) end = 1; else end = 0;
12898 			us_clearhighlightcount();
12899 			high.status = HIGHFROM;
12900 			high.cell = ai->parent;
12901 			high.fromgeom = ai->end[end].nodeinst->geom;
12902 			high.fromport = ai->end[end].portarcinst->proto;
12903 			high.frompoint = 0;
12904 			high.fromvar = NOVARIABLE;
12905 			high.fromvarnoeval = NOVARIABLE;
12906 			us_addhighlight(&high);
12907 			us_showallhighlight();
12908 			us_endchanges(NOWINDOWPART);
12909 			continue;
12910 		}
12911 	}
12912 
12913 	if (itemHit != CANCEL && changed)
12914 	{
12915 		us_pushhighlight();
12916 		us_clearhighlightcount();
12917 		startobjectchange((INTBIG)ai, VARCINST);
12918 		lambda = lambdaofarc(ai);
12919 		wid = atola(DiaGetText(dia, DGIA_WIDTH), lambda);
12920 		if (wid < 0) wid = oldwid;
12921 		wid = arcwidthoffset(ai) + wid;
12922 		startobjectchange((INTBIG)ai, VARCINST);
12923 		if (DiaGetControl(dia, DGIA_RIGID) == 0)
12924 		{
12925 			if (DiaGetControl(dia, DGIA_TEMPORARY) == 0) rigstate = 1; else
12926 				rigstate = 3;
12927 		} else
12928 		{
12929 			if (DiaGetControl(dia, DGIA_TEMPORARY) == 0) rigstate = 0; else
12930 				rigstate = 2;
12931 		}
12932 		if (rigstate != oldrigstate) switch (rigstate)
12933 		{
12934 			case 0:
12935 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPEREMOVETEMP, 0);
12936 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPERIGID, 0);
12937 				break;
12938 			case 1:
12939 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPEREMOVETEMP, 0);
12940 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPEUNRIGID, 0);
12941 				break;
12942 			case 2:
12943 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPETEMPRIGID, 0);
12944 				break;
12945 			case 3:
12946 				(void)(*el_curconstraint->setobject)((INTBIG)ai, VARCINST, CHANGETYPETEMPUNRIGID, 0);
12947 				break;
12948 		}
12949 		i = DiaGetControl(dia, DGIA_FIXANGLE);
12950 		if (i != 0 && (ai->userbits&FIXANG) == 0)
12951 			(void)(*el_curconstraint->setobject)((INTBIG)ai,VARCINST,CHANGETYPEFIXEDANGLE,0);
12952 		if (i == 0 && (ai->userbits&FIXANG) != 0)
12953 			(void)(*el_curconstraint->setobject)((INTBIG)ai,VARCINST,CHANGETYPENOTFIXEDANGLE,0);
12954 		i = DiaGetControl(dia, DGIA_SLIDABLE);
12955 		if (i != 0 && (ai->userbits&CANTSLIDE) != 0)
12956 			(void)(*el_curconstraint->setobject)((INTBIG)ai,VARCINST,CHANGETYPESLIDABLE,0);
12957 		if (i == 0 && (ai->userbits&CANTSLIDE) == 0)
12958 			(void)(*el_curconstraint->setobject)((INTBIG)ai,VARCINST,CHANGETYPENOTSLIDABLE,0);
12959 		i = DiaGetControl(dia, DGIA_NEGATED);
12960 		if (i != 0 && (ai->userbits&ISNEGATED) == 0)
12961 			(void)setval((INTBIG)ai, VARCINST,x_("userbits"), ai->userbits | ISNEGATED, VINTEGER);
12962 		if (i == 0 && (ai->userbits&ISNEGATED) != 0)
12963 			(void)setval((INTBIG)ai, VARCINST,x_("userbits"), ai->userbits & ~ISNEGATED, VINTEGER);
12964 		i = DiaGetControl(dia, DGIA_DIRECTIONAL);
12965 		if (i != 0 && (ai->userbits&ISDIRECTIONAL) == 0)
12966 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits | ISDIRECTIONAL, VINTEGER);
12967 		if (i == 0 && (ai->userbits&ISDIRECTIONAL) != 0)
12968 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits & ~ISDIRECTIONAL, VINTEGER);
12969 		i = DiaGetControl(dia, DGIA_ENDEXTEND);
12970 		if (i != 0 && (ai->userbits&NOEXTEND) != 0)
12971 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits & ~NOEXTEND, VINTEGER);
12972 		if (i == 0 && (ai->userbits&NOEXTEND) == 0)
12973 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits | NOEXTEND, VINTEGER);
12974 		i = DiaGetControl(dia, DGIA_IGNOREHEAD);
12975 		if (i != 0 && (ai->userbits&NOTEND1) == 0)
12976 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits | NOTEND1, VINTEGER);
12977 		if (i == 0 && (ai->userbits&NOTEND1) != 0)
12978 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits & ~NOTEND1, VINTEGER);
12979 		i = DiaGetControl(dia, DGIA_IGNORETAIL);
12980 		if (i != 0 && (ai->userbits&NOTEND0) == 0)
12981 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits | NOTEND0, VINTEGER);
12982 		if (i == 0 && (ai->userbits&NOTEND0) != 0)
12983 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits & ~NOTEND0, VINTEGER);
12984 		i = DiaGetControl(dia, DGIA_REVERSE);
12985 		if (i != 0 && (ai->userbits&REVERSEEND) == 0)
12986 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits | REVERSEEND, VINTEGER);
12987 		if (i == 0 && (ai->userbits&REVERSEEND) != 0)
12988 			(void)setval((INTBIG)ai, VARCINST, x_("userbits"), ai->userbits & ~REVERSEEND, VINTEGER);
12989 		if (DiaGetControl(dia, DGIA_EASYSELECT) != 0) ai->userbits &= ~HARDSELECTA; else
12990 			ai->userbits |= HARDSELECTA;
12991 		newstr = DiaGetText(dia, DGIA_NAME);
12992 		while (*newstr == ' ') newstr++;
12993 		if (estrcmp(str, newstr) != 0)
12994 		{
12995 			if (*newstr == 0) us_setarcname(ai, (CHAR *)0); else
12996 				us_setarcname(ai, newstr);
12997 		}
12998 		(void)modifyarcinst(ai, wid - ai->width, 0, 0, 0, 0);
12999 
13000 		/* update color if it changed */
13001 		if (ai->proto->tech == art_tech)
13002 		{
13003 			i = DiaGetPopupEntry(dia, DGIA_EXTRAINFO);
13004 			if (us_colorvaluelist[i] == BLACK)
13005 			{
13006 				var = getvalkey((INTBIG)ai, VARCINST, VINTEGER, art_colorkey);
13007 				if (var != NOVARIABLE)
13008 					(void)delvalkey((INTBIG)ai, VARCINST, art_colorkey);
13009 			} else
13010 			{
13011 				setvalkey((INTBIG)ai, VARCINST, art_colorkey, us_colorvaluelist[i], VINTEGER);
13012 			}
13013 		}
13014 		endobjectchange((INTBIG)ai, VARCINST);
13015 		us_pophighlight(FALSE);
13016 	}
13017 	DiaDoneDialog(dia);
13018 	if (itemHit == DGIA_HEADINFO || itemHit == DGIA_TAILINFO)
13019 	{
13020 		if (itemHit == DGIA_HEADINFO) end = 1; else end = 0;
13021 		us_clearhighlightcount();
13022 		high.status = HIGHFROM;
13023 		high.cell = ai->parent;
13024 		high.fromgeom = ai->end[end].nodeinst->geom;
13025 		high.fromport = ai->end[end].portarcinst->proto;
13026 		high.frompoint = 0;
13027 		high.fromvar = NOVARIABLE;
13028 		high.fromvarnoeval = NOVARIABLE;
13029 		us_addhighlight(&high);
13030 		us_showallhighlight();
13031 		us_endchanges(NOWINDOWPART);
13032 		us_getinfonode(ai->end[end].nodeinst, FALSE);
13033 	}
13034 	if (itemHit == DGIA_ATTRIBUTES)
13035 	{
13036 		us_endchanges(NOWINDOWPART);
13037 		(void)us_attributesdlog();
13038 	}
13039 }
13040 
us_getnodedisplaysize(NODEINST * ni,INTBIG * xsize,INTBIG * ysize)13041 void us_getnodedisplaysize(NODEINST *ni, INTBIG *xsize, INTBIG *ysize)
13042 {
13043 	REGISTER BOOLEAN xyrev, serptrans;
13044 	REGISTER INTBIG fun;
13045 	INTBIG plx, ply, phx, phy;
13046 	REGISTER VARIABLE *var;
13047 
13048 	serptrans = FALSE;
13049 	if (ni->proto->primindex != 0)
13050 	{
13051 		fun = (ni->proto->userbits&NFUNCTION) >> NFUNCTIONSH;
13052 		if (fun == NPTRANMOS || fun == NPTRADMOS || fun == NPTRAPMOS)
13053 		{
13054 			var = gettrace(ni);
13055 			if (var != NOVARIABLE) serptrans = TRUE;
13056 		}
13057 	}
13058 
13059 	xyrev = FALSE;
13060 	if (!serptrans)
13061 	{
13062 		if (ni->transpose == 0)
13063 		{
13064 			if (ni->rotation == 900 || ni->rotation == 2700) xyrev = TRUE;
13065 		} else
13066 		{
13067 			if (ni->rotation == 0 || ni->rotation == 1800) xyrev = TRUE;
13068 		}
13069 	}
13070 	nodesizeoffset(ni, &plx, &ply, &phx, &phy);
13071 	if (!xyrev)
13072 	{
13073 		*xsize = ni->highx-ni->lowx-plx-phx;
13074 		*ysize = ni->highy-ni->lowy-ply-phy;
13075 	} else
13076 	{
13077 		*xsize = ni->highy-ni->lowy-ply-phy;
13078 		*ysize = ni->highx-ni->lowx-plx-phx;
13079 	}
13080 }
13081 
us_getnodemodfromdisplayinfo(NODEINST * ni,INTBIG xs,INTBIG ys,INTBIG xc,INTBIG yc,INTBIG r,INTBIG t,BOOLEAN positionchanged,INTBIG * dlx,INTBIG * dly,INTBIG * dhx,INTBIG * dhy,INTBIG * drot,INTBIG * dtran,BOOLEAN xyrev)13082 void us_getnodemodfromdisplayinfo(NODEINST *ni, INTBIG xs, INTBIG ys, INTBIG xc, INTBIG yc,
13083 	INTBIG r, INTBIG t, BOOLEAN positionchanged, INTBIG *dlx, INTBIG *dly, INTBIG *dhx,
13084 	INTBIG *dhy, INTBIG *drot, INTBIG *dtran, BOOLEAN xyrev)
13085 {
13086 	INTBIG plx, ply, phx, phy, cox, coy;
13087 	REGISTER INTBIG dx, dy, nlx, nhx, nly, nhy, swap;
13088 	REGISTER VARIABLE *var;
13089 	XARRAY trans;
13090 
13091 	nodesizeoffset(ni, &plx, &ply, &phx, &phy);
13092 	if (xyrev)
13093 	{
13094 		swap = xs;   xs = ys;   ys = swap;
13095 		xc -= (phy-ply)/2;
13096 		yc -= (phx-plx)/2;
13097 	} else
13098 	{
13099 		xc -= (phx-plx)/2;
13100 		yc -= (phy-ply)/2;
13101 	}
13102 	*dlx = *dhx = *dly = *dhy = 0;
13103 	*drot = *dtran = 0;
13104 	corneroffset(ni, ni->proto, ni->rotation, ni->transpose, &cox, &coy, FALSE);
13105 	if (positionchanged || r != ni->rotation || t != ni->transpose ||
13106 		xs != ni->highx-ni->lowx-plx-phx || ys != ni->highy-ni->lowy-ply-phy)
13107 	{
13108 		if (!positionchanged)
13109 		{
13110 			/* only size changed: adjust position appropriately */
13111 			dx = (xs + plx + phx) - (ni->highx - ni->lowx);
13112 			dy = (ys + ply + phy) - (ni->highy - ni->lowy);
13113 			nlx = ni->lowx - dx/2;
13114 			nhx = nlx + xs + plx + phx;
13115 			nly = ni->lowy - dy/2;
13116 			nhy = nly + ys + ply + phy;
13117 			*dlx = nlx-ni->lowx;
13118 			*dly = nly-ni->lowy;
13119 			*dhx = nhx-ni->highx;
13120 			*dhy = nhy-ni->highy;
13121 			*drot = r - ni->rotation;
13122 			*dtran = t - ni->transpose;
13123 		} else
13124 		{
13125 
13126 			/* position (and possibly size) changed: update from dialog */
13127 			if ((us_useroptions&CENTEREDPRIMITIVES) == 0)
13128 			{
13129 				dx = xc - ni->lowx - cox;   dy = yc - ni->lowy - coy;
13130 				nlx = ni->lowx + dx;
13131 				nhx = nlx + xs + plx + phx;
13132 				nly = ni->lowy + dy;
13133 				nhy = nly + ys + ply + phy;
13134 			} else
13135 			{
13136 				var = getvalkey((INTBIG)ni->proto, VNODEPROTO, VINTEGER|VISARRAY, el_prototype_center_key);
13137 				if (var != NOVARIABLE)
13138 				{
13139 					dx = ((INTBIG *)var->addr)[0] + (ni->lowx+ni->highx)/2 -
13140 						(ni->proto->lowx+ni->proto->highx)/2;
13141 					dy = ((INTBIG *)var->addr)[1] + (ni->lowy+ni->highy)/2 -
13142 						(ni->proto->lowy+ni->proto->highy)/2;
13143 					makerot(ni, trans);
13144 					xform(dx, dy, &cox, &coy, trans);
13145 					xc -= cox - (ni->lowx+ni->highx)/2;
13146 					yc -= coy - (ni->lowy+ni->highy)/2;
13147 				}
13148 				nlx = xc - xs/2 - (plx+phx)/2;
13149 				nhx = nlx + xs + plx + phx;
13150 				nly = yc - ys/2 - (ply+phy)/2;
13151 				nhy = nly + ys + ply + phy;
13152 			}
13153 			*dlx = nlx-ni->lowx;
13154 			*dly = nly-ni->lowy;
13155 			*dhx = nhx-ni->highx;
13156 			*dhy = nhy-ni->highy;
13157 			*drot = r - ni->rotation;
13158 			*dtran = t - ni->transpose;
13159 		}
13160 	}
13161 }
13162 
13163 /* Get Info: Node */
13164 static DIALOGITEM us_shownodedialogitems[] =
13165 {
13166  /*  1 */ {0, {32,8,48,56}, MESSAGE, N_("Name:")},
13167  /*  2 */ {0, {8,8,24,56}, MESSAGE, N_("Type:")},
13168  /*  3 */ {0, {32,64,48,392}, EDITTEXT, x_("")},
13169  /*  4 */ {0, {8,64,24,392}, MESSAGE, x_("")},
13170  /*  5 */ {0, {76,80,92,176}, EDITTEXT, x_("")},
13171  /*  6 */ {0, {100,80,116,174}, EDITTEXT, x_("")},
13172  /*  7 */ {0, {56,76,72,193}, MESSAGE, x_("")},
13173  /*  8 */ {0, {100,8,116,72}, MESSAGE, N_("Y size:")},
13174  /*  9 */ {0, {76,8,92,72}, MESSAGE, N_("X size:")},
13175  /* 10 */ {0, {76,208,92,288}, MESSAGE, N_("X position:")},
13176  /* 11 */ {0, {76,296,92,392}, EDITTEXT, x_("")},
13177  /* 12 */ {0, {100,296,116,390}, EDITTEXT, x_("")},
13178  /* 13 */ {0, {100,208,116,288}, MESSAGE, N_("Y position:")},
13179  /* 14 */ {0, {56,292,72,392}, MESSAGE, N_("Lower-left:")},
13180  /* 15 */ {0, {124,8,140,72}, MESSAGE, N_("Rotation:")},
13181  /* 16 */ {0, {124,80,140,128}, EDITTEXT, x_("")},
13182  /* 17 */ {0, {124,136,140,246}, AUTOCHECK, N_("Transposed")},
13183  /* 18 */ {0, {124,264,140,392}, AUTOCHECK, N_("Easy to Select")},
13184  /* 19 */ {0, {148,32,172,104}, BUTTON, N_("More")},
13185  /* 20 */ {0, {148,120,172,192}, BUTTON, N_("Close")},
13186  /* 21 */ {0, {148,208,172,280}, BUTTON, N_("Apply")},
13187  /* 22 */ {0, {148,300,172,372}, DEFBUTTON, N_("OK")},
13188  /* 23 */ {0, {180,8,196,104}, RADIOA, N_("Expanded")},
13189  /* 24 */ {0, {180,112,196,216}, RADIOA, N_("Unexpanded")},
13190  /* 25 */ {0, {180,220,196,392}, AUTOCHECK, N_("Only Visible Inside Cell")},
13191  /* 26 */ {0, {229,8,245,156}, MESSAGE, x_("")},
13192  /* 27 */ {0, {205,8,221,156}, MESSAGE, x_("")},
13193  /* 28 */ {0, {205,160,221,392}, EDITTEXT, x_("")},
13194  /* 29 */ {0, {229,160,245,392}, POPUP, x_("")},
13195  /* 30 */ {0, {256,20,272,108}, RADIOB, N_("Ports:")},
13196  /* 31 */ {0, {256,124,272,244}, RADIOB, N_("Parameters:")},
13197  /* 32 */ {0, {256,260,272,380}, RADIOB, N_("Attributes")},
13198  /* 33 */ {0, {276,8,404,392}, SCROLL, x_("")},
13199  /* 34 */ {0, {416,12,432,104}, AUTOCHECK, N_("Locked")},
13200  /* 35 */ {0, {412,212,436,284}, BUTTON, N_("Get Info")},
13201  /* 36 */ {0, {412,316,436,388}, BUTTON, N_("Attributes")},
13202  /* 37 */ {0, {445,161,461,393}, EDITTEXT, x_("")},
13203  /* 38 */ {0, {469,161,485,393}, POPUP, x_("")},
13204  /* 39 */ {0, {493,161,509,393}, MESSAGE, x_("")},
13205  /* 40 */ {0, {493,9,509,161}, MESSAGE, x_("")},
13206  /* 41 */ {0, {469,9,485,161}, MESSAGE, x_("")},
13207  /* 42 */ {0, {445,9,461,157}, MESSAGE, x_("")}
13208 };
13209 static DIALOG us_shownodedialog = {{50,75,568,478}, N_("Node Information"), 0, 42, us_shownodedialogitems, x_("shownode"), 176};
13210 
13211 /* special items for the "shownode" dialog: */
13212 #define DGIN_NAME_L         1		/* Name label (message) */
13213 #define DGIN_TYPE_L         2		/* Type label (message) */
13214 #define DGIN_NAME           3		/* Name (edittext) */
13215 #define DGIN_TYPE           4		/* Type (message) */
13216 #define DGIN_XSIZE          5		/* X size (edittext) */
13217 #define DGIN_YSIZE          6		/* Y size (edittext) */
13218 #define DGIN_SIZE           7		/* Size information (message) */
13219 #define DGIN_YSIZE_L        8		/* Y size label (message) */
13220 #define DGIN_XSIZE_L        9		/* X size label (message) */
13221 #define DGIN_XPOSITION_L   10		/* X position label (message) */
13222 #define DGIN_XPOSITION     11		/* X position (edittext) */
13223 #define DGIN_YPOSITION     12		/* Y position (edittext) */
13224 #define DGIN_YPOSITION_L   13		/* Y position label (message) */
13225 #define DGIN_POSITION      14		/* Position information (message) */
13226 #define DGIN_ROTATTION_L   15		/* Rotation label (message) */
13227 #define DGIN_ROTATION      16		/* Rotation (edittext) */
13228 #define DGIN_TRANSPOSE     17		/* Transposed (autocheck) */
13229 #define DGIN_EASYSELECT    18		/* Easy to Select (autocheck) */
13230 #define DGIN_MOREORLESS    19		/* More/Less (button) */
13231 #define DGIN_CLOSE         20		/* Close (button) */
13232 #define DGIN_APPLY         21		/* Apply changes (button) */
13233 #define DGIN_OK            22		/* OK (defbutton) */
13234 #define DGIN_EXPANDED      23		/* expanded (radioa) */
13235 #define DGIN_UNEXPANDED    24		/* unexpanded (radioa) */
13236 #define DGIN_VISINSIDE     25		/* Only visible inside cell (autocheck) */
13237 #define DGIN_SPECIAL2_L    26		/* Special line 2 title (message) */
13238 #define DGIN_SPECIAL1_L    27		/* Special line 1 title (message) */
13239 #define DGIN_SPECIAL1      28		/* Special line 1 value (edittext) */
13240 #define DGIN_SPECIAL2      29		/* Special line 2 value (popup) */
13241 #define DGIN_SEEPORTS      30		/* Show ports in list (radiob) */
13242 #define DGIN_SEEPARAMETERS 31		/* Show parameters in list (radiob) */
13243 #define DGIN_SEEATTRIBUTES 32		/* Show parameters in list (radiob) */
13244 #define DGIN_CONLIST       33		/* connection list (scroll) */
13245 #define DGIN_NODELOCKED    34		/* Node is locked (autocheck) */
13246 #define DGIN_GETINFO       35		/* Get Info on arc/export (button) */
13247 #define DGIN_ATTRIBUTES    36		/* Attributes (button) */
13248 #define DGIN_PARATTR       37		/* Parameter/attribute value (edittext) */
13249 #define DGIN_PARATTRLAN    38		/* Parameter/attribute language (popup) */
13250 #define DGIN_PARATTREV     39		/* Parameter/attribute evaluation (message) */
13251 #define DGIN_PARATTREV_L   40		/* Parameter/attribute evaluation title (message) */
13252 #define DGIN_PARATTRLAN_L  41		/* Parameter/attribute language title (message) */
13253 #define DGIN_PARATTR_L     42		/* Parameter/attribute name (message) */
13254 
13255 #define PARAMDEFAULTSTRING _(" (default)")
13256 
13257 class EDiaShowNode : public EDialogModeless
13258 {
13259 public:
13260 	EDiaShowNode();
13261 	~EDiaShowNode();
13262 	void reset();
13263 	void geomhaschanged(GEOM *geom);
13264 	void highlighthaschanged(void);
13265 	void refill();
13266 
13267 	static EDiaShowNode *dialog;        /* dialog instance */
13268 	static BOOLEAN showmoreinited;		/* TRUE if "showmore" is initialized */
13269 	static BOOLEAN showmore;			/* TRUE if in fullsize mode */
13270 private:
13271 	void itemHitAction(INTBIG itemHit);
13272 	void setState(BOOLEAN valid);
13273 	void setEditable(BOOLEAN ediatble);
13274 	INTBIG chatportproto(PORTPROTO *pp, PORTPROTO *selected, INTBIG lineno);
13275 
13276 	NODEINST  *ni;						/* the node being displayed in the dialog */
13277 	BOOLEAN    makingchanges;			/* TRUE if updating the current node (ignore broadcasts) */
13278 	BOOLEAN    xyrev;					/* TRUE if X and Y are reversed */
13279 	INTBIG     paramcount;				/* number of parameters */
13280 	INTBIG     paramtotal;				/* allocated space for parameters */
13281 	INTBIG    *paramlanguage;			/* language information for each parameter */
13282 	CHAR     **paramname;				/* name for each parameter */
13283 	CHAR     **paramvalue;				/* value for each parameter */
13284 	CHAR     **parameval;				/* evaluated value for each parameter */
13285 
13286 	INTBIG     attrcount;				/* number of attributes */
13287 	INTBIG     attrtotal;				/* allocated space for attributes */
13288 	INTBIG    *attrlanguage;			/* language information for each attribute */
13289 	CHAR     **attrname;				/* name for each attribute */
13290 	CHAR     **attrvalue;				/* value for each attribute */
13291 	CHAR     **attreval;				/* evaluated value for each attribute */
13292 
13293 	INTBIG     serpwidth;				/* serpentine transistor width (negative if not relevant) */
13294 	BOOLEAN    techedrel;				/* TRUE if from technology editor */
13295 	CHAR      *initialeditfield;		/* initial value for special nodes */
13296 	CHAR      *namestr;					/* initial node name */
13297 	INTBIG     listcontents;			/* item number of what is in "more" list (ports, attributes, parameters) */
13298 	BOOLEAN    changed;					/* TRUE if something changed in the dialog */
13299 	BOOLEAN    positionchanged;			/* TRUE if position changed in the dialog */
13300 	INTBIG     highlineno;				/* line highlighted in list */
13301 	ARCINST   *selectedai;				/* the ARCINST that is selected in the port list */
13302 	PORTPROTO *selectedpp;				/* the export that is selected in the port list */
13303 	VARIABLE  *unitvar;					/* variable that holds miscellaneous units */
13304 	double     startoffset, endangle;	/* for describing circles */
13305 };
13306 
13307 EDiaShowNode *EDiaShowNode::dialog = 0;
13308 BOOLEAN       EDiaShowNode::showmore;
13309 BOOLEAN       EDiaShowNode::showmoreinited = FALSE;
13310 
13311 /*
13312  * Routine called when this object is modified
13313  */
us_geomhaschanged(GEOM * geom)13314 void us_geomhaschanged(GEOM *geom)
13315 {
13316 	if (EDiaShowNode::dialog == 0) return;
13317 	EDiaShowNode::dialog->geomhaschanged(geom);
13318 }
13319 
13320 /*
13321  * Routine called when highlight is modified
13322  */
us_highlighthaschanged(void)13323 void us_highlighthaschanged(void)
13324 {
13325 	if (EDiaShowNode::dialog == 0) return;
13326 	EDiaShowNode::dialog->highlighthaschanged();
13327 }
13328 
us_getinfonode(NODEINST * ni,BOOLEAN canspecialize)13329 void us_getinfonode(NODEINST *ni, BOOLEAN canspecialize)
13330 {
13331 	REGISTER NODEPROTO *np;
13332 	REGISTER INTBIG fun;
13333 
13334 	/* see if specialized dialogs should be shown */
13335 	if (canspecialize)
13336 	{
13337 		np = ni->proto;
13338 		if (np == mocmos_scalablentransprim || np == mocmos_scalableptransprim)
13339 		{
13340 			(void)us_scalabletransdlog();
13341 			return;
13342 		}
13343 		if (np == sch_globalprim)
13344 		{
13345 			(void)us_globalsignaldlog();
13346 			return;
13347 		}
13348 		fun = nodefunction(ni);
13349 		if (fun == NPRESIST)
13350 		{
13351 			us_resistancedlog(ni->geom, NOVARIABLE);
13352 			return;
13353 		}
13354 		if (fun == NPCAPAC || fun == NPECAPAC)
13355 		{
13356 			us_capacitancedlog(ni->geom, NOVARIABLE);
13357 			return;
13358 		}
13359 		if (fun == NPINDUCT)
13360 		{
13361 			us_inductancedlog(ni->geom, NOVARIABLE);
13362 			return;
13363 		}
13364 		if (fun == NPDIODE || fun == NPDIODEZ)
13365 		{
13366 			us_areadlog(ni);
13367 			return;
13368 		}
13369 		if (np == sch_transistorprim || np == sch_transistor4prim)
13370 		{
13371 			switch (fun)
13372 			{
13373 				case NPTRANMOS:  case NPTRA4NMOS:  us_widlendlog(ni);  return;
13374 				case NPTRADMOS:  case NPTRA4DMOS:  us_widlendlog(ni);  return;
13375 				case NPTRAPMOS:  case NPTRA4PMOS:  us_widlendlog(ni);  return;
13376 				case NPTRANPN:   case NPTRA4NPN:   us_areadlog(ni);    return;
13377 				case NPTRAPNP:   case NPTRA4PNP:   us_areadlog(ni);    return;
13378 				case NPTRANJFET: case NPTRA4NJFET: us_widlendlog(ni);  return;
13379 				case NPTRAPJFET: case NPTRA4PJFET: us_widlendlog(ni);  return;
13380 				case NPTRADMES:  case NPTRA4DMES:  us_widlendlog(ni);  return;
13381 				case NPTRAEMES:  case NPTRA4EMES:  us_widlendlog(ni);  return;
13382 			}
13383 		}
13384 	}
13385 
13386 	/* if the dialog is already up, just show it */
13387 	if (EDiaShowNode::dialog == 0)
13388 	{
13389 		if (!EDiaShowNode::showmoreinited)
13390 		{
13391 			EDiaShowNode::showmoreinited = TRUE;
13392 			if ((us_useroptions&EXPANDEDDIALOGSDEF) != 0) EDiaShowNode::showmore = TRUE; else
13393 				EDiaShowNode::showmore = FALSE;
13394 		}
13395 		if (EDiaShowNode::showmore)
13396 		{
13397 			us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("Less");
13398 		} else
13399 		{
13400 			us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("More");
13401 		}
13402 		EDiaShowNode::dialog = new EDiaShowNode();
13403 	}
13404 	EDiaShowNode::dialog->refill();
13405 }
13406 
EDiaShowNode()13407 EDiaShowNode::EDiaShowNode() : EDialogModeless(&us_shownodedialog)
13408 {
13409 	paramtotal = 0;
13410 	attrtotal = 0;
13411 	reset();
13412 };
13413 
~EDiaShowNode()13414 EDiaShowNode::~EDiaShowNode()
13415 {
13416 	if (paramtotal > 0)
13417 	{
13418 		for(int i=0; i<paramtotal; i++)
13419 		{
13420 			if (paramname[i] != 0) efree((CHAR *)paramname[i]);
13421 			if (paramvalue[i] != 0) efree((CHAR *)paramvalue[i]);
13422 			if (parameval[i] != 0) efree((CHAR *)parameval[i]);
13423 		}
13424 		efree((CHAR*)paramlanguage);
13425 		efree((CHAR*)paramname);
13426 		efree((CHAR*)paramvalue);
13427 		efree((CHAR*)parameval);
13428 	}
13429 	if (attrtotal > 0)
13430 	{
13431 		for(int i=0; i<attrtotal; i++)
13432 		{
13433 			if (attrname[i] != 0) efree((CHAR *)attrname[i]);
13434 			if (attrvalue[i] != 0) efree((CHAR *)attrvalue[i]);
13435 			if (attreval[i] != 0) efree((CHAR *)attreval[i]);
13436 		}
13437 		efree((CHAR*)attrlanguage);
13438 		efree((CHAR*)attrname);
13439 		efree((CHAR*)attrvalue);
13440 		efree((CHAR*)attreval);
13441 	}
13442 }
13443 
reset()13444 void EDiaShowNode::reset()
13445 {
13446 	if ((us_useroptions&EXPANDEDDIALOGSDEF) != 0) showmore = TRUE; else
13447 		showmore = FALSE;
13448 	showExtension( showmore );
13449 	if (showmore)
13450 	{
13451 		us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("Less");
13452 	} else
13453 	{
13454 		us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("More");
13455 	}
13456 	setText(DGIN_MOREORLESS, us_shownodedialogitems[DGIN_MOREORLESS-1].msg);
13457 
13458 	initialeditfield = 0;
13459 	listcontents = DGIN_SEEPORTS;
13460 	makingchanges = FALSE;
13461 }
13462 
geomhaschanged(GEOM * geom)13463 void EDiaShowNode::geomhaschanged(GEOM *geom)
13464 {
13465 	REGISTER NODEINST *newNi;
13466 
13467 	if (isHidden() || makingchanges) return;
13468 	if (geom->entryisnode)
13469 	{
13470 		newNi = geom->entryaddr.ni;
13471 		if (newNi != ni) return;
13472 		refill();
13473 	}
13474 }
13475 
highlighthaschanged(void)13476 void EDiaShowNode::highlighthaschanged(void)
13477 {
13478 	if (isHidden() || makingchanges) return;
13479 	refill();
13480 }
13481 
13482 /*
13483  * Routine to setup the node "get info" dialog so that all fields are prepared.
13484  * If "valid" is TRUE, there is a valid node in the dialog (otherwise, clear everything).
13485  */
setState(BOOLEAN valid)13486 void EDiaShowNode::setState(BOOLEAN valid)
13487 {
13488 	/* reset everything, that can be changed */
13489 	paramcount = 0;
13490 	attrcount = 0;
13491 	loadTextDialog(DGIN_CONLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
13492 	setText(DGIN_TYPE, x_(""));
13493 	setText(DGIN_NAME, x_(""));
13494 	setText(DGIN_XSIZE, x_(""));
13495 	setText(DGIN_YSIZE, x_(""));
13496 	setText(DGIN_XSIZE_L, _("X size:"));
13497 	setText(DGIN_YSIZE_L, _("Y size:"));
13498 	setText(DGIN_ROTATION, x_(""));
13499 	setControl(DGIN_TRANSPOSE, 0);
13500 	setText(DGIN_SIZE, x_(""));
13501 	setText(DGIN_XPOSITION, x_(""));
13502 	setText(DGIN_YPOSITION, x_(""));
13503 	setText(DGIN_POSITION, _("Lower-left:"));
13504 	setControl(DGIN_EASYSELECT, 0);
13505 	setControl(DGIN_VISINSIDE, 0);
13506 	dimItem(DGIN_SEEPARAMETERS);
13507 	dimItem(DGIN_SEEATTRIBUTES);
13508 	setText(DGIN_SPECIAL1, x_(""));
13509 	setText(DGIN_SPECIAL1_L, x_(""));
13510 	setPopup(DGIN_SPECIAL2, 0, NULL);
13511 	setText(DGIN_SPECIAL2_L, x_(""));
13512 	dimItem(DGIN_APPLY);
13513 	setControl(DGIN_NODELOCKED, 0);
13514 	setText(DGIN_PARATTR, x_(""));
13515 	setText(DGIN_PARATTR_L, x_(""));
13516 	setText(DGIN_PARATTREV, x_(""));
13517 	setText(DGIN_PARATTREV_L, x_(""));
13518 	setText(DGIN_PARATTRLAN_L, x_(""));
13519 
13520 	if (valid)
13521 	{
13522 		/* have a node: enable everything */
13523 		unDimItem(DGIN_SEEPORTS);
13524 		unDimItem(DGIN_GETINFO);
13525 		unDimItem(DGIN_ATTRIBUTES);
13526 		unDimItem(DGIN_APPLY);
13527 	} else
13528 	{
13529 		/* no node: disable everything */
13530 		dimItem(DGIN_SEEPORTS);
13531 		dimItem(DGIN_GETINFO);
13532 		dimItem(DGIN_ATTRIBUTES);
13533 		dimItem(DGIN_APPLY);
13534 	}
13535 	setEditable( valid );
13536 }
13537 
13538 /*
13539  * Routine to change state of editable fields.
13540  * If "editable" is TRUE, let the fields be changed (otherwise, dim the value fields).
13541  */
setEditable(BOOLEAN editable)13542 void EDiaShowNode::setEditable(BOOLEAN editable)
13543 {
13544 	if (editable)
13545 	{
13546 		unDimItem(DGIN_EXPANDED);
13547 		unDimItem(DGIN_UNEXPANDED);
13548 		unDimItem(DGIN_NAME);
13549 		unDimItem(DGIN_XSIZE);
13550 		unDimItem(DGIN_YSIZE);
13551 		unDimItem(DGIN_ROTATION);
13552 		unDimItem(DGIN_TRANSPOSE);
13553 		unDimItem(DGIN_XPOSITION);
13554 		unDimItem(DGIN_YPOSITION);
13555 		unDimItem(DGIN_EASYSELECT);
13556 		unDimItem(DGIN_VISINSIDE);
13557 		unDimItem(DGIN_PARATTR);
13558 		unDimItem(DGIN_PARATTRLAN);
13559 		unDimItem(DGIN_SPECIAL1);
13560 		unDimItem(DGIN_SPECIAL2);
13561 	} else
13562 	{
13563 		dimItem(DGIN_EXPANDED);
13564 		dimItem(DGIN_UNEXPANDED);
13565 		dimItem(DGIN_NAME);
13566 		dimItem(DGIN_XSIZE);
13567 		dimItem(DGIN_YSIZE);
13568 		dimItem(DGIN_ROTATION);
13569 		dimItem(DGIN_TRANSPOSE);
13570 		dimItem(DGIN_XPOSITION);
13571 		dimItem(DGIN_YPOSITION);
13572 		dimItem(DGIN_EASYSELECT);
13573 		dimItem(DGIN_VISINSIDE);
13574 		dimItem(DGIN_PARATTR);
13575 		dimItem(DGIN_PARATTRLAN);
13576 		dimItem(DGIN_SPECIAL1);
13577 		dimItem(DGIN_SPECIAL2);
13578 	}
13579 }
13580 
13581 /*
13582  * Routine to fill-in the node "get info" dialog with the currently selected node.
13583  *
13584  * There are two lines in the full dialog that have special meaning for special nodes:
13585  *    Node Type					Line 1 (edit)	Line 2 (popup)
13586  *    -------------------------	-------------	--------------
13587  *    MOS Serpentine Transistor	Width/Length
13588  *    Scalable MOS Transistor	Width
13589  *    Schematic Transistor		Type
13590  *    Diode						Size
13591  *    Resistor					Ohms
13592  *    Capacitor					Farads
13593  *    Inductor					Henrys
13594  *    Black-box					Function
13595  *    Flip-flop									Type
13596  *    Global					Name			Characteristics
13597  *    Technology-edit object	Type
13598  *    Artwork primitive							Color
13599  *    Artwork circle			Degrees
13600  */
refill(void)13601 void EDiaShowNode::refill(void)
13602 {
13603 	REGISTER NODEPROTO *np, *cnp;
13604 	REGISTER PORTPROTO *pp, *fromport;
13605 	REGISTER INTBIG lambda, i, j, fun, lineno, xsize, ysize;
13606 	REGISTER BOOLEAN holdsoutline, line1used, line2used;
13607 	INTBIG plx, phx, ply, phy, xpos, ypos, len, wid;
13608 	REGISTER VARIABLE *var, *ovar;
13609 	REGISTER CHAR *pt;
13610 	CHAR **languages, ent[100], *newlang[25], *colorname, *colorsymbol;
13611 	REGISTER UINTBIG characteristics;
13612 	REGISTER void *infstr;
13613 	HIGHLIGHT high;
13614 	static CHAR *transistortype[9] = {N_("N-type MOS"), N_("Depletion MOS"), N_("P-type MOS"),
13615 		N_("NPN Bipolar"), N_("PNP Bipolar"), N_("N-type JFET"), N_("P-type JFET"), N_("Depletion MESFET"),
13616 		N_("Enhancement MESFET")};
13617 	static CHAR *flipfloptype[12] = {N_("RS Master/slave"), N_("JK Master/slave"), N_("D Master/slave"),
13618 		N_("T Master/slave"), N_("RS Positive"), N_("JK Positive"), N_("D Positive"),
13619 		N_("T Positive"), N_("RS Negative"), N_("JK Negative"), N_("D Negative"),
13620 		N_("T Negative")};
13621 
13622 	/* ensure dialog visible */
13623 	show();
13624 
13625 	/* see what is selected */
13626 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
13627 	if (var == NOVARIABLE)
13628 	{
13629 		/* clear the dialog */
13630 		setState(FALSE);
13631 		ni = NONODEINST;
13632 		return;
13633 	}
13634 	if (getlength(var) != 1)
13635 	{
13636 		/* too much highlighted: clear the dialog */
13637 		setState(FALSE);
13638 		ni = NONODEINST;
13639 		return;
13640 	}
13641 	if (us_makehighlight(((CHAR **)var->addr)[0], &high)) return;
13642 	if ((high.status&HIGHTYPE) != HIGHFROM)
13643 	{
13644 		/* no object selected: clear the dialog */
13645 		setState(FALSE);
13646 		ni = NONODEINST;
13647 		return;
13648 	}
13649 	if (!high.fromgeom->entryisnode)
13650 	{
13651 		/* no node selected: clear the dialog */
13652 		setState(FALSE);
13653 		ni = NONODEINST;
13654 		return;
13655 	}
13656 	ni = high.fromgeom->entryaddr.ni;
13657 	fromport = high.fromport;
13658 	np = ni->proto;
13659 	lambda = lambdaofnode(ni);
13660 	if (initialeditfield != 0)
13661 	{
13662 		efree((CHAR *)initialeditfield);
13663 		initialeditfield = 0;
13664 	}
13665 	line1used = line2used = FALSE;
13666 
13667 	/* things that may become dimmed: start them undimmed */
13668 	setState(TRUE);
13669 
13670 	/* count the number of attributes on the node */
13671 	attrcount = 0;
13672 	for(i=0; i<ni->numvar; i++)
13673 	{
13674 		var = &ni->firstvar[i];
13675 		if (TDGETISPARAM(var->textdescript) != 0) continue;
13676 		pt = makename(var->key);
13677 		if (namesamen(pt, x_("ATTR_"), 5) == 0) attrcount++;
13678 	}
13679 
13680 	/* make sure there is space */
13681 	if (attrcount > attrtotal)
13682 	{
13683 		if (attrtotal > 0)
13684 		{
13685 			for(i=0; i<attrtotal; i++)
13686 			{
13687 				if (attrname[i] != 0) efree((CHAR *)attrname[i]);
13688 				if (attrvalue[i] != 0) efree((CHAR *)attrvalue[i]);
13689 				if (attreval[i] != 0) efree((CHAR *)attreval[i]);
13690 			}
13691 			efree((CHAR *)attrlanguage);
13692 			efree((CHAR *)attrname);
13693 			efree((CHAR *)attrvalue);
13694 			efree((CHAR *)attreval);
13695 		}
13696 		attrtotal = 0;
13697 		attrname = (CHAR **)emalloc(attrcount * (sizeof (CHAR *)), us_tool->cluster);
13698 		attrvalue = (CHAR **)emalloc(attrcount * (sizeof (CHAR *)), us_tool->cluster);
13699 		attreval = (CHAR **)emalloc(attrcount * (sizeof (CHAR *)), us_tool->cluster);
13700 		attrlanguage = (INTBIG *)emalloc(attrcount * SIZEOFINTBIG, us_tool->cluster);
13701 		if (attrname == 0 || attrvalue == 0 ||
13702 			attreval == 0 || attrlanguage == 0) return;
13703 		attrtotal = attrcount;
13704 		for(i=0; i<attrtotal; i++)
13705 		{
13706 			attrname[i] = 0;
13707 			attrvalue[i] = 0;
13708 			attreval[i] = 0;
13709 		}
13710 	}
13711 
13712 	/* gather the attributes */
13713 	if (attrcount > 0)
13714 	{
13715 		attrcount = 0;
13716 		for(i=0; i<ni->numvar; i++)
13717 		{
13718 			var = &ni->firstvar[i];
13719 			if (TDGETISPARAM(var->textdescript) != 0) continue;
13720 			pt = makename(var->key);
13721 			if (namesamen(pt, x_("ATTR_"), 5) != 0) continue;
13722 			if (attrname[attrcount] != 0)
13723 				efree((CHAR *)attrname[attrcount]);
13724 			if (attrvalue[attrcount] != 0)
13725 				efree((CHAR *)attrvalue[attrcount]);
13726 			if (attreval[attrcount] != 0)
13727 				efree((CHAR *)attreval[attrcount]);
13728 
13729 			(void)allocstring(&attrname[attrcount],
13730 				truevariablename(var), us_tool->cluster);
13731 			(void)allocstring(&attrvalue[attrcount],
13732 				describevariable(var, -1, -1), us_tool->cluster);
13733 			(void)allocstring(&attreval[attrcount],
13734 				describevariable(evalvar(var, (INTBIG)ni, VNODEINST), -1, -1),
13735 					us_tool->cluster);
13736 			attrlanguage[attrcount] = var->type & (VCODE1|VCODE2);
13737 			attrcount++;
13738 		}
13739 	}
13740 
13741 	/* see if this node has parameters */
13742 	paramcount = 0;
13743 	cnp = NONODEPROTO;
13744 	if (np->primindex == 0)
13745 	{
13746 		/* see if there are parameters on the instance */
13747 		cnp = contentsview(np);
13748 		if (cnp == NONODEPROTO) cnp = np;
13749 		for(i=0; i<cnp->numvar; i++)
13750 		{
13751 			var = &cnp->firstvar[i];
13752 			if (TDGETISPARAM(var->textdescript) != 0) paramcount++;
13753 		}
13754 	}
13755 
13756 	/* make sure there is space */
13757 	if (paramcount > paramtotal)
13758 	{
13759 		if (paramtotal > 0)
13760 		{
13761 			for(i=0; i<paramtotal; i++)
13762 			{
13763 				if (paramname[i] != 0) efree((CHAR *)paramname[i]);
13764 				if (paramvalue[i] != 0) efree((CHAR *)paramvalue[i]);
13765 				if (parameval[i] != 0) efree((CHAR *)parameval[i]);
13766 			}
13767 			efree((CHAR *)paramlanguage);
13768 			efree((CHAR *)paramname);
13769 			efree((CHAR *)paramvalue);
13770 			efree((CHAR *)parameval);
13771 		}
13772 		paramtotal = 0;
13773 		paramname = (CHAR **)emalloc(paramcount * (sizeof (CHAR *)), us_tool->cluster);
13774 		paramvalue = (CHAR **)emalloc(paramcount * (sizeof (CHAR *)), us_tool->cluster);
13775 		parameval = (CHAR **)emalloc(paramcount * (sizeof (CHAR *)), us_tool->cluster);
13776 		paramlanguage = (INTBIG *)emalloc(paramcount * SIZEOFINTBIG, us_tool->cluster);
13777 		if (paramname == 0 || paramvalue == 0 ||
13778 			parameval == 0 || paramlanguage == 0) return;
13779 		paramtotal = paramcount;
13780 		for(i=0; i<paramtotal; i++)
13781 		{
13782 			paramname[i] = 0;
13783 			paramvalue[i] = 0;
13784 			parameval[i] = 0;
13785 		}
13786 	}
13787 
13788 	/* gather the parameters */
13789 	if (paramcount > 0)
13790 	{
13791 		paramcount = 0;
13792 		for(i=0; i<cnp->numvar; i++)
13793 		{
13794 			var = &cnp->firstvar[i];
13795 			if (TDGETISPARAM(var->textdescript) == 0) continue;
13796 			if (paramname[paramcount] != 0)
13797 				efree((CHAR *)paramname[paramcount]);
13798 			if (paramvalue[paramcount] != 0)
13799 				efree((CHAR *)paramvalue[paramcount]);
13800 			if (parameval[paramcount] != 0)
13801 				efree((CHAR *)parameval[paramcount]);
13802 
13803 			(void)allocstring(&paramname[paramcount],
13804 				truevariablename(var), us_tool->cluster);
13805 			for(j=0; j<ni->numvar; j++)
13806 			{
13807 				ovar = &ni->firstvar[j];
13808 				if (TDGETISPARAM(ovar->textdescript) == 0) continue;
13809 				if (namesame(truevariablename(var), truevariablename(ovar)) != 0) continue;
13810 				(void)allocstring(&paramvalue[paramcount],
13811 					describevariable(ovar, -1, -1), us_tool->cluster);
13812 				(void)allocstring(&parameval[paramcount],
13813 					describevariable(evalvar(ovar, (INTBIG)ni, VNODEINST), -1, -1), us_tool->cluster);
13814 				paramlanguage[paramcount] = ovar->type & (VCODE1|VCODE2);
13815 				break;
13816 			}
13817 			if (j >= ni->numvar)
13818 			{
13819 				infstr = initinfstr();
13820 				addstringtoinfstr(infstr, describevariable(var, -1, -1));
13821 				addstringtoinfstr(infstr, PARAMDEFAULTSTRING);
13822 				(void)allocstring(&paramvalue[paramcount],
13823 					returninfstr(infstr), us_tool->cluster);
13824 				(void)allocstring(&parameval[paramcount],
13825 					describevariable(evalvar(var, (INTBIG)cnp, VNODEPROTO), -1, -1), us_tool->cluster);
13826 				paramlanguage[paramcount] = 0;
13827 			}
13828 			paramcount++;
13829 		}
13830 	}
13831 
13832 	/* show the appropriate list */
13833 	if (listcontents == DGIN_SEEPARAMETERS && paramcount == 0)
13834 	{
13835 		if (attrcount > 0) listcontents = DGIN_SEEATTRIBUTES; else
13836 			listcontents = DGIN_SEEPORTS;
13837 	}
13838 	if (listcontents == DGIN_SEEATTRIBUTES && attrcount == 0)
13839 	{
13840 		if (paramcount > 0) listcontents = DGIN_SEEPARAMETERS; else
13841 			listcontents = DGIN_SEEPORTS;
13842 	}
13843 	setControl(DGIN_SEEPARAMETERS, 0);
13844 	setControl(DGIN_SEEATTRIBUTES, 0);
13845 	setControl(DGIN_SEEPORTS, 0);
13846 	setControl(listcontents, 1);
13847 	if (paramcount == 0) dimItem(DGIN_SEEPARAMETERS); else
13848 		unDimItem(DGIN_SEEPARAMETERS);
13849 	if (attrcount == 0) dimItem(DGIN_SEEATTRIBUTES); else
13850 		unDimItem(DGIN_SEEATTRIBUTES);
13851 	dimItem(DGIN_PARATTRLAN_L);
13852 	dimItem(DGIN_PARATTRLAN);
13853 	if (paramcount != 0 || attrcount != 0)
13854 	{
13855 		languages = us_languagechoices();
13856 		if (paramcount != 0 && attrcount != 0)
13857 		{
13858 			setText(DGIN_PARATTRLAN_L, _("Parameter/Attribute type:"));
13859 		} else if (paramcount != 0)
13860 		{
13861 			setText(DGIN_PARATTRLAN_L, _("Parameter type:"));
13862 		} else if (attrcount != 0)
13863 		{
13864 			setText(DGIN_PARATTRLAN_L, _("Attribute type:"));
13865 		}
13866 		setPopup(DGIN_PARATTRLAN, 4, languages);
13867 		unDimItem(DGIN_PARATTR);
13868 		unDimItem(DGIN_PARATTRLAN_L);
13869 		unDimItem(DGIN_PARATTRLAN);
13870 	}
13871 	initTextDialog(DGIN_CONLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
13872 		SCSELMOUSE|SCREPORT|SCHORIZBAR);
13873 
13874 	if (listcontents == DGIN_SEEPARAMETERS)
13875 	{
13876 		/* show all parameters */
13877 		highlineno = -1;
13878 		if (paramcount == 0)
13879 		{
13880 			setText(DGIN_PARATTR, x_(""));
13881 			dimItem(DGIN_PARATTR);
13882 		}
13883 		for(i=0; i<paramcount; i++)
13884 		{
13885 			infstr = initinfstr();
13886 			formatinfstr(infstr, x_("%s = %s"), paramname[i], paramvalue[i]);
13887 			stuffLine(DGIN_CONLIST, returninfstr(infstr));
13888 			if (highlineno < 0)
13889 			{
13890 				infstr = initinfstr();
13891 				formatinfstr(infstr, x_("Parameter '%s'"), paramname[i]);
13892 				setText(DGIN_PARATTR_L, returninfstr(infstr));
13893 				unDimItem(DGIN_PARATTR);
13894 				setText(DGIN_PARATTR, paramvalue[i]);
13895 				switch (paramlanguage[i])
13896 				{
13897 					case 0:     setPopupEntry(DGIN_PARATTRLAN, 0);   break;
13898 					case VTCL:  setPopupEntry(DGIN_PARATTRLAN, 1);   break;
13899 					case VLISP: setPopupEntry(DGIN_PARATTRLAN, 2);   break;
13900 					case VJAVA: setPopupEntry(DGIN_PARATTRLAN, 3);   break;
13901 				}
13902 				if (paramlanguage[i] != 0)
13903 				{
13904 					setText(DGIN_PARATTREV_L, _("Evaluation:"));
13905 					setText(DGIN_PARATTREV, parameval[i]);
13906 				}
13907 				highlineno = i;
13908 			}
13909 		}
13910 		selectLine(DGIN_CONLIST, highlineno);
13911 	} else if (listcontents == DGIN_SEEATTRIBUTES)
13912 	{
13913 		/* show all attributes */
13914 		highlineno = -1;
13915 		if (attrcount == 0)
13916 		{
13917 			setText(DGIN_PARATTR, x_(""));
13918 			dimItem(DGIN_PARATTR);
13919 		}
13920 		for(i=0; i<attrcount; i++)
13921 		{
13922 			infstr = initinfstr();
13923 			formatinfstr(infstr, x_("%s = %s"), attrname[i], attrvalue[i]);
13924 			stuffLine(DGIN_CONLIST, returninfstr(infstr));
13925 			if (highlineno < 0)
13926 			{
13927 				infstr = initinfstr();
13928 				formatinfstr(infstr, x_("Attribute '%s'"), attrname[i]);
13929 				setText(DGIN_PARATTR_L, returninfstr(infstr));
13930 				unDimItem(DGIN_PARATTR);
13931 				setText(DGIN_PARATTR, attrvalue[i]);
13932 				switch (attrlanguage[i])
13933 				{
13934 					case 0:     setPopupEntry(DGIN_PARATTRLAN, 0);   break;
13935 					case VTCL:  setPopupEntry(DGIN_PARATTRLAN, 1);   break;
13936 					case VLISP: setPopupEntry(DGIN_PARATTRLAN, 2);   break;
13937 					case VJAVA: setPopupEntry(DGIN_PARATTRLAN, 3);   break;
13938 				}
13939 				if (attrlanguage[i] != 0)
13940 				{
13941 					setText(DGIN_PARATTREV_L, _("Evaluation:"));
13942 					setText(DGIN_PARATTREV, attreval[i]);
13943 				}
13944 				highlineno = i;
13945 			}
13946 		}
13947 		selectLine(DGIN_CONLIST, highlineno);
13948 	} else
13949 	{
13950 		/* describe all ports */
13951 		setText(DGIN_PARATTR, x_(""));
13952 		dimItem(DGIN_PARATTR);
13953 		lineno = 0;
13954 		highlineno = -1;
13955 		for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
13956 		{
13957 			if (pp == fromport) highlineno = lineno;
13958 			lineno = chatportproto(pp, fromport, lineno);
13959 		}
13960 		selectLine(DGIN_CONLIST, highlineno);
13961 	}
13962 	dimItem(DGIN_GETINFO);
13963 
13964 	/* see if this node has outline information */
13965 	holdsoutline = FALSE;
13966 	var = gettrace(ni);
13967 	if (var != NOVARIABLE)
13968 	{
13969 		holdsoutline = TRUE;
13970 		dimItem(DGIN_XSIZE);
13971 		dimItem(DGIN_YSIZE);
13972 	}
13973 
13974 	/* if there is outline information on a transistor, remember that */
13975 	serpwidth = -1;
13976 	fun = (np->userbits&NFUNCTION) >> NFUNCTIONSH;
13977 	if (fun == NPTRANMOS || fun == NPTRADMOS || fun == NPTRAPMOS)
13978 	{
13979 		if (np->primindex != 0 && (np->userbits&HOLDSTRACE) != 0 && holdsoutline)
13980 		{
13981 			/* serpentine transistor: show width, edit length */
13982 			serpwidth = 0;
13983 			transistorsize(ni, &len, &wid);
13984 			if (len != -1 && wid != -1)
13985 			{
13986 				esnprintf(ent, 100, _("Width=%s; Length:"), latoa(wid, lambda));
13987 				setText(DGIN_SPECIAL1_L, ent);
13988 				(void)allocstring(&initialeditfield, latoa(len, lambda), us_tool->cluster);
13989 				setText(DGIN_SPECIAL1, initialeditfield);
13990 				serpwidth = len;
13991 				line1used = TRUE;
13992 			}
13993 		}
13994 	}
13995 
13996 	/* load the prototype name */
13997 	setText(DGIN_TYPE, describenodeproto(np));
13998 
13999 	/* load the node name if any */
14000 	var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
14001 	if (var != NOVARIABLE)
14002 	{
14003 		namestr = (CHAR *)var->addr;
14004 		setText(-DGIN_NAME, namestr);
14005 	} else namestr = x_("");
14006 
14007 	/* load the size */
14008 	xyrev = FALSE;
14009 	if ((fun == NPTRANMOS || fun == NPTRADMOS || fun == NPTRAPMOS) && serpwidth < 0)
14010 	{
14011 		if (np == mocmos_scalablentransprim || np == mocmos_scalableptransprim)
14012 			setText(DGIN_XSIZE_L, _("Max Width:")); else
14013 				setText(DGIN_XSIZE_L, _("Width:"));
14014 		setText(DGIN_YSIZE_L, _("Length:"));
14015 	} else
14016 	{
14017 		if (ni->transpose == 0)
14018 		{
14019 			if (ni->rotation == 900 || ni->rotation == 2700) xyrev = TRUE;
14020 		} else
14021 		{
14022 			if (ni->rotation == 0 || ni->rotation == 1800) xyrev = TRUE;
14023 		}
14024 		if (xyrev) setText(DGIN_SIZE, _("Transformed:")); else
14025 		{
14026 			if ((ni->rotation%900) != 0)
14027 				setText(DGIN_SIZE, _("Untransformed:"));
14028 		}
14029 	}
14030 	nodesizeoffset(ni, &plx, &ply, &phx, &phy);
14031 	if (xyrev)
14032 	{
14033 		xsize = ni->highy-ni->lowy-ply-phy;
14034 		ysize = ni->highx-ni->lowx-plx-phx;
14035 	} else
14036 	{
14037 		xsize = ni->highx-ni->lowx-plx-phx;
14038 		ysize = ni->highy-ni->lowy-ply-phy;
14039 	}
14040 	setText(DGIN_XSIZE, latoa(xsize, lambda));
14041 	setText(DGIN_YSIZE, latoa(ysize, lambda));
14042 
14043 	/* load the position */
14044 	if ((us_useroptions&CENTEREDPRIMITIVES) != 0)
14045 	{
14046 		var = getvalkey((INTBIG)ni->proto, VNODEPROTO, VINTEGER|VISARRAY, el_prototype_center_key);
14047 		if (var != NOVARIABLE)
14048 		{
14049 			setText(DGIN_POSITION, _("Cell center:"));
14050 		} else
14051 		{
14052 			setText(DGIN_POSITION, _("Center:"));
14053 		}
14054 	}
14055 	us_getnodedisplayposition(ni, &xpos, &ypos);
14056 	setText(DGIN_XPOSITION, latoa(xpos, lambda));
14057 	setText(DGIN_YPOSITION, latoa(ypos, lambda));
14058 
14059 	/* load rotation */
14060 	setText(DGIN_ROTATION, frtoa(ni->rotation*WHOLE/10));
14061 	if (ni->transpose != 0) setControl(DGIN_TRANSPOSE, 1);
14062 
14063 	/* set the expansion button */
14064 	if (np->primindex == 0)
14065 	{
14066 		if ((ni->userbits&NEXPAND) != 0) i = DGIN_EXPANDED; else i = DGIN_UNEXPANDED;
14067 		setControl(i, 1);
14068 		noEditControl(DGIN_XSIZE);
14069 		noEditControl(DGIN_YSIZE);
14070 	} else
14071 	{
14072 		dimItem(DGIN_EXPANDED);
14073 		dimItem(DGIN_UNEXPANDED);
14074 		editControl(DGIN_XSIZE);
14075 		editControl(DGIN_YSIZE);
14076 	}
14077 	if ((ni->userbits&NVISIBLEINSIDE) != 0) setControl(DGIN_VISINSIDE, 1);
14078 
14079 	/* load easy of selection */
14080 	if ((ni->userbits&HARDSELECTN) == 0) setControl(DGIN_EASYSELECT, 1);
14081 	if (np->primindex == 0 && (us_useroptions&NOINSTANCESELECT) != 0)
14082 		dimItem(DGIN_EASYSELECT);
14083 
14084 	/* load locked state */
14085 	if ((ni->userbits&NILOCKED) != 0) setControl(DGIN_NODELOCKED, 1);
14086 
14087 	/* load special node information */
14088 	if (np == sch_diodeprim)
14089 	{
14090 		if ((ni->userbits&NTECHBITS) == DIODEZENER)
14091 			setText(DGIN_SPECIAL1_L, _("Zener diode size:")); else
14092 				setText(DGIN_SPECIAL1_L, _("Diode size:"));
14093 		var = getvalkey((INTBIG)ni, VNODEINST, -1, sch_diodekey);
14094 		if (var == NOVARIABLE) pt = x_("0"); else
14095 			pt = describesimplevariable(var);
14096 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14097 		setText(DGIN_SPECIAL1, initialeditfield);
14098 		line1used = TRUE;
14099 	}
14100 	if (np == sch_resistorprim)
14101 	{
14102 		infstr = initinfstr();
14103 		addstringtoinfstr(infstr, _("Resistance"));
14104 		formatinfstr(infstr, x_(" (%s):"),
14105 			TRANSLATE(us_resistancenames[(us_electricalunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH]));
14106 		setText(DGIN_SPECIAL1_L, returninfstr(infstr));
14107 		unitvar = getvalkey((INTBIG)ni, VNODEINST, -1, sch_resistancekey);
14108 		if (unitvar == NOVARIABLE) pt = x_("0"); else
14109 			pt = describevariable(unitvar, -1, -1);
14110 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14111 		setText(DGIN_SPECIAL1, initialeditfield);
14112 		line1used = TRUE;
14113 	}
14114 	if (np == sch_capacitorprim)
14115 	{
14116 		infstr = initinfstr();
14117 		if ((ni->userbits&NTECHBITS) == CAPACELEC)
14118 			addstringtoinfstr(infstr, _("Electrolytic cap:")); else
14119 				addstringtoinfstr(infstr, _("Capacitance"));
14120 		formatinfstr(infstr, x_(" (%s):"),
14121 			TRANSLATE(us_capacitancenames[(us_electricalunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH]));
14122 		setText(DGIN_SPECIAL1_L, returninfstr(infstr));
14123 		unitvar = getvalkey((INTBIG)ni, VNODEINST, -1, sch_capacitancekey);
14124 		if (unitvar == NOVARIABLE) pt = x_("0"); else
14125 			pt = describevariable(unitvar, -1, -1);
14126 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14127 		setText(DGIN_SPECIAL1, initialeditfield);
14128 		line1used = TRUE;
14129 	}
14130 	if (np == sch_inductorprim)
14131 	{
14132 		infstr = initinfstr();
14133 		addstringtoinfstr(infstr, _("Inductance"));
14134 		formatinfstr(infstr, x_(" (%s):"),
14135 			TRANSLATE(us_inductancenames[(us_electricalunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH]));
14136 		setText(DGIN_SPECIAL1_L, returninfstr(infstr));
14137 		unitvar = getvalkey((INTBIG)ni, VNODEINST, -1, sch_inductancekey);
14138 		if (unitvar == NOVARIABLE) pt = x_("0"); else
14139 			pt = describevariable(unitvar, -1, -1);
14140 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14141 		setText(DGIN_SPECIAL1, initialeditfield);
14142 		line1used = TRUE;
14143 	}
14144 	if (np == sch_bboxprim)
14145 	{
14146 		setText(DGIN_SPECIAL1_L, _("Function:"));
14147 		var = getvalkey((INTBIG)ni, VNODEINST, -1, sch_functionkey);
14148 		if (var == NOVARIABLE) pt = x_(""); else
14149 			pt = describesimplevariable(var);
14150 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14151 		setText(DGIN_SPECIAL1, initialeditfield);
14152 		line1used = TRUE;
14153 	}
14154 	if (np == sch_transistorprim || np == sch_transistor4prim)
14155 	{
14156 		switch (nodefunction(ni))
14157 		{
14158 			case NPTRANMOS:  case NPTRA4NMOS:  i = 0;  break;
14159 			case NPTRADMOS:  case NPTRA4DMOS:  i = 1;  break;
14160 			case NPTRAPMOS:  case NPTRA4PMOS:  i = 2;  break;
14161 			case NPTRANPN:   case NPTRA4NPN:   i = 3;  break;
14162 			case NPTRAPNP:   case NPTRA4PNP:   i = 4;  break;
14163 			case NPTRANJFET: case NPTRA4NJFET: i = 5;  break;
14164 			case NPTRAPJFET: case NPTRA4PJFET: i = 6;  break;
14165 			case NPTRADMES:  case NPTRA4DMES:  i = 7;  break;
14166 			case NPTRAEMES:  case NPTRA4EMES:  i = 8;  break;
14167 		}
14168 		setText(DGIN_SPECIAL1_L, _("Transistor type:"));
14169 		setText(DGIN_SPECIAL1, TRANSLATE(transistortype[i]));
14170 		line1used = TRUE;
14171 	}
14172 	if (np == sch_ffprim)
14173 	{
14174 		setText(DGIN_SPECIAL2_L, _("Flip-flop type:"));
14175 		for(i=0; i<12; i++) newlang[i] = TRANSLATE(flipfloptype[i]);
14176 		setPopup(DGIN_SPECIAL2, 12, newlang);
14177 		switch (ni->userbits&FFTYPE)
14178 		{
14179 			case FFTYPERS: i = 0;   break;
14180 			case FFTYPEJK: i = 1;   break;
14181 			case FFTYPED:  i = 2;   break;
14182 			case FFTYPET:  i = 3;   break;
14183 		}
14184 		switch (ni->userbits&FFCLOCK)
14185 		{
14186 			case FFCLOCKMS: i += 0;   break;
14187 			case FFCLOCKP:  i += 4;   break;
14188 			case FFCLOCKN:  i += 8;   break;
14189 		}
14190 		setPopupEntry(DGIN_SPECIAL2, i);
14191 		line2used = TRUE;
14192 	}
14193 	if (np == sch_globalprim)
14194 	{
14195 		setText(DGIN_SPECIAL1_L, _("Global name:"));
14196 		setText(DGIN_SPECIAL2_L, _("Characteristics:"));
14197 		for(i=0; i<NUMPORTCHARS; i++) newlang[i] = TRANSLATE(us_exportcharnames[i]);
14198 		setPopup(DGIN_SPECIAL2, NUMPORTCHARS, newlang);
14199 		characteristics = ((ni->userbits&NTECHBITS) >> NTECHBITSSH) << STATEBITSSH;
14200 		for(i=0; i<NUMPORTCHARS; i++)
14201 			if (us_exportcharlist[i] == characteristics)
14202 		{
14203 			setPopupEntry(DGIN_SPECIAL2, i);
14204 			break;
14205 		}
14206 		var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_globalnamekey);
14207 		if (var != NOVARIABLE)
14208 		{
14209 			(void)allocstring(&initialeditfield, (CHAR *)var->addr, us_tool->cluster);
14210 			setText(DGIN_SPECIAL1, initialeditfield);
14211 		}
14212 		line1used = line2used = TRUE;
14213 	}
14214 	if (np == mocmos_scalablentransprim || np == mocmos_scalableptransprim)
14215 	{
14216 		var = getvalkey((INTBIG)ni, VNODEINST, -1, el_attrkey_width);
14217 		if (var == NOVARIABLE) pt = x_(""); else
14218 			pt = describesimplevariable(var);
14219 		(void)allocstring(&initialeditfield, pt, us_tool->cluster);
14220 		if (var == NOVARIABLE)
14221 		{
14222 			(void)allocstring(&initialeditfield, latoa(xsize, lambda), us_tool->cluster);
14223 			setText(DGIN_SPECIAL1_L, _("Actual width:"));
14224 			setText(DGIN_SPECIAL1, initialeditfield);
14225 		}
14226 		line1used = TRUE;
14227 	}
14228 
14229 	/* get technology-edit relevance */
14230 	techedrel = FALSE;
14231 	pt = us_teceddescribenode(ni);
14232 	if (pt != 0)
14233 	{
14234 		setText(DGIN_SPECIAL2_L, _("Tech. edit relevance:"));
14235 		newlang[0] = pt;
14236 		setPopup(DGIN_SPECIAL2, 1, newlang);
14237 		dimItem(DGIN_SPECIAL2);
14238 		line2used = TRUE;
14239 		techedrel = TRUE;
14240 	} else if (np->primindex != 0 && np->tech == art_tech)
14241 	{
14242 		setText(DGIN_SPECIAL2_L, _("Color:"));
14243 		for(i=0; i<25; i++)
14244 		{
14245 			(void)ecolorname(us_colorvaluelist[i], &colorname, &colorsymbol);
14246 			newlang[i] = TRANSLATE(colorname);
14247 		}
14248 		setPopup(DGIN_SPECIAL2, 25, newlang);
14249 		var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, art_colorkey);
14250 		if (var == NOVARIABLE) i = 6; else
14251 		{
14252 			for(i=0; i<25; i++) if (us_colorvaluelist[i] == var->addr) break;
14253 		}
14254 		setPopupEntry(DGIN_SPECIAL2, i);
14255 		line2used = TRUE;
14256 	}
14257 
14258 	/* load the degrees of a circle if appropriate */
14259 	if (np == art_circleprim || np == art_thickcircleprim)
14260 	{
14261 		getarcdegrees(ni, &startoffset, &endangle);
14262 		if (startoffset != 0.0)
14263 		{
14264 			setText(DGIN_SPECIAL1_L, _("Offset angle / Degrees of circle:"));
14265 			esnprintf(ent, 100, x_("%g / %g"), startoffset*180.0/EPI, endangle*180.0/EPI);
14266 			(void)allocstring(&initialeditfield, ent, us_tool->cluster);
14267 			setText(DGIN_SPECIAL1, initialeditfield);
14268 		} else
14269 		{
14270 			setText(DGIN_SPECIAL1_L, _("Degrees of circle:"));
14271 			if (endangle == 0.0) setText(DGIN_SPECIAL1, x_("360")); else
14272 			{
14273 				esnprintf(ent, 100, x_("%g"), endangle*180.0/EPI);
14274 				(void)allocstring(&initialeditfield, ent, us_tool->cluster);
14275 				setText(DGIN_SPECIAL1, initialeditfield);
14276 			}
14277 		}
14278 		line1used = TRUE;
14279 	}
14280 
14281 	/* if the special lines weren't used, clear them */
14282 	if (!line1used)
14283 	{
14284 		setText(DGIN_SPECIAL1_L, x_(""));
14285 		setText(DGIN_SPECIAL1, x_(""));
14286 		dimItem(DGIN_SPECIAL1);
14287 	}
14288 	if (!line2used)
14289 	{
14290 		setText(DGIN_SPECIAL2_L, x_(""));
14291 		setPopup(DGIN_SPECIAL2, 0, 0);
14292 		dimItem(DGIN_SPECIAL2);
14293 	}
14294 
14295 	/* if the node can't be edited, disable all changes */
14296 	if (us_cantedit(ni->parent, ni, FALSE))
14297 		setEditable(FALSE);
14298 
14299 	changed = FALSE;
14300 	positionchanged = FALSE;
14301 	selectedai = NOARCINST;
14302 	selectedpp = NOPORTPROTO;
14303 }
14304 
14305 /*
14306  * Coroutine to handle hits in the modeless "layer visibility" dialog.
14307  */
itemHitAction(INTBIG itemHit)14308 void EDiaShowNode::itemHitAction(INTBIG itemHit)
14309 {
14310 	REGISTER INTBIG i, lambda, xs, ys, xc, yc, r, t,
14311 		j, len, dlen;
14312 	UINTBIG newbits;
14313 	INTBIG dlx, dhx, dly, dhy, drot, dtran, newtype, newaddr, type, addr;
14314 	float value;
14315 	double newstart, newend;
14316 	REGISTER NODEPROTO *np;
14317 	REGISTER VARIABLE *var;
14318 	REGISTER ARCINST *ai;
14319 	REGISTER PORTPROTO *pp;
14320 	REGISTER PORTARCINST *pi;
14321 	REGISTER PORTEXPINST *pe;
14322 	REGISTER void *infstr;
14323 	CHAR *newstr, *str;
14324 	HIGHLIGHT high;
14325 	UINTBIG descript[TEXTDESCRIPTSIZE];
14326 
14327 	/* the "Info" button shows a dialog of info about the selected arc or export */
14328 	if (itemHit == DGIN_GETINFO)
14329 	{
14330 		if (selectedai != NOARCINST)
14331 		{
14332 			us_clearhighlightcount();
14333 			high.status = HIGHFROM;
14334 			high.cell = selectedai->parent;
14335 			high.fromgeom = selectedai->geom;
14336 			high.fromport = NOPORTPROTO;
14337 			high.frompoint = 0;
14338 			high.fromvar = NOVARIABLE;
14339 			high.fromvarnoeval = NOVARIABLE;
14340 			us_addhighlight(&high);
14341 			us_showallhighlight();
14342 			us_endchanges(NOWINDOWPART);
14343 			us_getinfoarc(selectedai);
14344 			return;
14345 		}
14346 		if (selectedpp != NOPORTPROTO)
14347 		{
14348 			us_clearhighlightcount();
14349 			high.status = HIGHTEXT;
14350 			high.cell = selectedpp->parent;
14351 			high.fromgeom = selectedpp->subnodeinst->geom;
14352 			high.fromport = selectedpp;
14353 			high.frompoint = 0;
14354 			high.fromvar = NOVARIABLE;
14355 			high.fromvarnoeval = NOVARIABLE;
14356 			us_addhighlight(&high);
14357 			us_showallhighlight();
14358 			us_endchanges(NOWINDOWPART);
14359 			us_getinfoexport(&high);
14360 			return;
14361 		}
14362 		return;
14363 	}
14364 
14365 	/* the "attributes" button shows parameter/attribute information */
14366 	if (itemHit == DGIN_ATTRIBUTES)
14367 	{
14368 		us_endchanges(NOWINDOWPART);
14369 		(void)us_attributesdlog();
14370 		return;
14371 	}
14372 
14373 	if (itemHit == DGIN_MOREORLESS)
14374 	{
14375 		showmore = !showmore;
14376 		if (showmore)
14377 			us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("Less"); else
14378 	            us_shownodedialogitems[DGIN_MOREORLESS-1].msg = _("More");
14379 		setText(DGIN_MOREORLESS, us_shownodedialogitems[DGIN_MOREORLESS-1].msg);
14380 		showExtension( showmore );
14381 		return;
14382 	}
14383 
14384 	if (itemHit == DGIN_SEEPORTS || itemHit == DGIN_SEEPARAMETERS ||
14385 		itemHit == DGIN_SEEATTRIBUTES)
14386 	{
14387 		listcontents = itemHit;
14388 		refill();
14389 		return;
14390 	}
14391 
14392 	if (itemHit == DGIN_TRANSPOSE || itemHit == DGIN_EASYSELECT ||
14393 		itemHit == DGIN_VISINSIDE || itemHit == DGIN_NODELOCKED ||
14394 		itemHit == DGIN_EXPANDED || itemHit == DGIN_UNEXPANDED)
14395 	{
14396 		changed = TRUE;
14397 		return;
14398 	}
14399 
14400 	if (itemHit == DGIN_NAME || itemHit == DGIN_XSIZE ||
14401 		itemHit == DGIN_YSIZE || itemHit == DGIN_ROTATION ||
14402 		itemHit == DGIN_PARATTR || itemHit == DGIN_PARATTRLAN ||
14403 		itemHit == DGIN_SPECIAL1 || itemHit == DGIN_SPECIAL2)
14404 			changed = TRUE;
14405 	if (itemHit == DGIN_XPOSITION || itemHit == DGIN_YPOSITION)
14406 	{
14407 		changed = TRUE;
14408 		positionchanged = TRUE;
14409 	}
14410 	if (itemHit == DGIN_PARATTRLAN)
14411 	{
14412 		if (listcontents == DGIN_SEEPORTS || highlineno < 0) return;
14413 		if (listcontents == DGIN_SEEPARAMETERS)
14414 		{
14415 			paramlanguage[highlineno] = 0;
14416 			switch (getPopupEntry(DGIN_PARATTRLAN))
14417 			{
14418 				case 1: paramlanguage[highlineno] |= VTCL;    break;
14419 				case 2: paramlanguage[highlineno] |= VLISP;   break;
14420 				case 3: paramlanguage[highlineno] |= VJAVA;   break;
14421 			}
14422 		} else
14423 		{
14424 			attrlanguage[highlineno] = 0;
14425 			switch (getPopupEntry(DGIN_PARATTRLAN))
14426 			{
14427 				case 1: attrlanguage[highlineno] |= VTCL;    break;
14428 				case 2: attrlanguage[highlineno] |= VLISP;   break;
14429 				case 3: attrlanguage[highlineno] |= VJAVA;   break;
14430 			}
14431 		}
14432 		return;
14433 	}
14434 
14435 	if (itemHit == DGIN_PARATTR)
14436 	{
14437 		if (listcontents == DGIN_SEEPORTS || highlineno < 0) return;
14438 		if (listcontents == DGIN_SEEPARAMETERS && highlineno < paramcount)
14439 		{
14440 			(void)reallocstring(&paramvalue[highlineno],
14441 				getText(DGIN_PARATTR), us_tool->cluster);
14442 			infstr = initinfstr();
14443 			formatinfstr(infstr, x_("%s = %s"), paramname[highlineno],
14444 				paramvalue[highlineno]);
14445 			setScrollLine(DGIN_CONLIST, highlineno, returninfstr(infstr));
14446 		}
14447 		if (listcontents == DGIN_SEEATTRIBUTES && highlineno < attrcount)
14448 		{
14449 			(void)reallocstring(&attrvalue[highlineno],
14450 				getText(DGIN_PARATTR), us_tool->cluster);
14451 			infstr = initinfstr();
14452 			formatinfstr(infstr, x_("%s = %s"), attrname[highlineno],
14453 				attrvalue[highlineno]);
14454 			setScrollLine(DGIN_CONLIST, highlineno, returninfstr(infstr));
14455 		}
14456 		return;
14457 	}
14458 
14459 	if (itemHit == DGIN_CONLIST)
14460 	{
14461 		if (ni == NONODEINST) return;
14462 		highlineno = getCurLine(DGIN_CONLIST);
14463 		if (listcontents == DGIN_SEEPARAMETERS)
14464 		{
14465 			infstr = initinfstr();
14466 			formatinfstr(infstr, x_("Parameter '%s'"), paramname[highlineno]);
14467 			setText(DGIN_PARATTR_L, returninfstr(infstr));
14468 			setText(DGIN_PARATTR, paramvalue[highlineno]);
14469 			switch (paramlanguage[highlineno])
14470 			{
14471 				case 0:     setPopupEntry(DGIN_PARATTRLAN, 0);   break;
14472 				case VTCL:  setPopupEntry(DGIN_PARATTRLAN, 1);   break;
14473 				case VLISP: setPopupEntry(DGIN_PARATTRLAN, 2);   break;
14474 				case VJAVA: setPopupEntry(DGIN_PARATTRLAN, 3);   break;
14475 			}
14476 			setText(DGIN_PARATTREV_L, x_(""));
14477 			setText(DGIN_PARATTREV, x_(""));
14478 			if (paramlanguage[highlineno] != 0)
14479 			{
14480 				setText(DGIN_PARATTREV_L, _("Evaluation:"));
14481 				setText(DGIN_PARATTREV, parameval[highlineno]);
14482 			}
14483 		} else if (listcontents == DGIN_SEEATTRIBUTES)
14484 		{
14485 			infstr = initinfstr();
14486 			formatinfstr(infstr, x_("Attribute '%s'"), attrname[highlineno]);
14487 			setText(DGIN_PARATTR_L, returninfstr(infstr));
14488 			setText(DGIN_PARATTR, attrvalue[highlineno]);
14489 			switch (attrlanguage[highlineno])
14490 			{
14491 				case 0:     setPopupEntry(DGIN_PARATTRLAN, 0);   break;
14492 				case VTCL:  setPopupEntry(DGIN_PARATTRLAN, 1);   break;
14493 				case VLISP: setPopupEntry(DGIN_PARATTRLAN, 2);   break;
14494 				case VJAVA: setPopupEntry(DGIN_PARATTRLAN, 3);   break;
14495 			}
14496 			setText(DGIN_PARATTREV_L, x_(""));
14497 			setText(DGIN_PARATTREV, x_(""));
14498 			if (attrlanguage[highlineno] != 0)
14499 			{
14500 				setText(DGIN_PARATTREV_L, _("Evaluation:"));
14501 				setText(DGIN_PARATTREV, attreval[highlineno]);
14502 			}
14503 		} else
14504 		{
14505 			selectedai = NOARCINST;
14506 			selectedpp = NOPORTPROTO;
14507 			ai = NOARCINST;
14508 			for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
14509 			{
14510 				ai = pi->conarcinst;
14511 				if (ai->temp2 == highlineno) break;
14512 			}
14513 			for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
14514 			{
14515 				pp = pe->exportproto;
14516 				if (pp->temp2 == highlineno) break;
14517 			}
14518 			if (pi == NOPORTARCINST && pe == NOPORTEXPINST)
14519 			{
14520 				dimItem(DGIN_GETINFO);
14521 				return;
14522 			}
14523 			unDimItem(DGIN_GETINFO);
14524 			if (pi != NOPORTARCINST)
14525 			{
14526 				selectedai = ai;
14527 			} else
14528 			{
14529 				selectedpp = pe->exportproto;
14530 			}
14531 		}
14532 		return;
14533 	}
14534 
14535 	if (itemHit == DGIN_OK || itemHit == DGIN_CLOSE || itemHit == DGIN_APPLY)
14536 	{
14537 		if (itemHit != DGIN_CLOSE && ni != NONODEINST && changed)
14538 		{
14539 			/* see if size, rotation, or position changed */
14540 			np = ni->proto;
14541 			makingchanges = TRUE;
14542 			lambda = lambdaofnode(ni);
14543 			xs = atola(getText(DGIN_XSIZE), lambda);
14544 			ys = atola(getText(DGIN_YSIZE), lambda);
14545 			xc = atola(getText(DGIN_XPOSITION), lambda);
14546 			yc = atola(getText(DGIN_YPOSITION), lambda);
14547 			r = atofr(getText(DGIN_ROTATION))*10/WHOLE;
14548 			t = (getControl(DGIN_TRANSPOSE) != 0 ? 1 : 0);
14549 			us_pushhighlight();
14550 			us_clearhighlightcount();
14551 			startobjectchange((INTBIG)ni, VNODEINST);
14552 			us_getnodemodfromdisplayinfo(ni, xs, ys, xc, yc, r, t, positionchanged,
14553 				&dlx, &dly, &dhx, &dhy, &drot, &dtran, xyrev);
14554 			modifynodeinst(ni, dlx, dly, dhx, dhy, drot, dtran);
14555 
14556 			newbits = ni->userbits;
14557 			if (getControl(DGIN_VISINSIDE) != 0) newbits |= NVISIBLEINSIDE; else
14558 				newbits &= ~NVISIBLEINSIDE;
14559 			if (getControl(DGIN_NODELOCKED) != 0) newbits |= NILOCKED; else
14560 				newbits &= ~NILOCKED;
14561 			if (newbits != ni->userbits)
14562 				(void)setval((INTBIG)ni, VNODEINST, x_("userbits"), newbits, VINTEGER);
14563 
14564 			/* update transistor width if it changed */
14565 			if (serpwidth >= 0)
14566 			{
14567 				newstr = getText(DGIN_SPECIAL1);
14568 				if (namesame(newstr, initialeditfield) != 0)
14569 				{
14570 					while (*newstr == ' ') newstr++;
14571 					lambda = lambdaofnode(ni);
14572 					if (*newstr != 0 && atola(newstr, lambda) != serpwidth)
14573 					{
14574 						(void)setvalkey((INTBIG)ni, VNODEINST, el_transistor_width_key,
14575 							atofr(newstr), VFRACT);
14576 					}
14577 				}
14578 			}
14579 
14580 			/* update diode area if it changed */
14581 			if (np == sch_diodeprim)
14582 			{
14583 				newstr = getText(DGIN_SPECIAL1);
14584 				if (namesame(newstr, initialeditfield) != 0)
14585 					us_setvariablevalue(ni->geom, sch_diodekey, newstr, VSTRING|VDISPLAY, 0);
14586 			}
14587 
14588 			/* update capacitance if it changed */
14589 			if (np == sch_capacitorprim)
14590 			{
14591 				newstr = getText(DGIN_SPECIAL1);
14592 				if (namesame(newstr, initialeditfield) != 0)
14593 				{
14594 					if (isanumber(newstr))
14595 					{
14596 						value = figureunits(newstr, VTUNITSCAP,
14597 							(us_electricalunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH);
14598 						us_setfloatvariablevalue(ni->geom, sch_capacitancekey, unitvar, value);
14599 					} else
14600 					{
14601 						TDCLEAR(descript);   defaulttextdescript(descript, ni->geom);  TDSETOFF(descript, 0, 0);
14602 						us_setvariablevalue(ni->geom, sch_capacitancekey, newstr, VDISPLAY, descript);
14603 					}
14604 				}
14605 			}
14606 
14607 			/* update resistance if it changed */
14608 			if (np == sch_resistorprim)
14609 			{
14610 				newstr = getText(DGIN_SPECIAL1);
14611 				if (namesame(newstr, initialeditfield) != 0)
14612 				{
14613 					if (isanumber(newstr))
14614 					{
14615 						value = figureunits(newstr, VTUNITSRES,
14616 							(us_electricalunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH);
14617 						us_setfloatvariablevalue(ni->geom, sch_resistancekey, unitvar, value);
14618 					} else
14619 					{
14620 						TDCLEAR(descript);   defaulttextdescript(descript, ni->geom);  TDSETOFF(descript, 0, 0);
14621 						us_setvariablevalue(ni->geom, sch_resistancekey, newstr, VDISPLAY, descript);
14622 					}
14623 				}
14624 			}
14625 
14626 			/* update inductance if it changed */
14627 			if (np == sch_inductorprim)
14628 			{
14629 				newstr = getText(DGIN_SPECIAL1);
14630 				if (namesame(newstr, initialeditfield) != 0)
14631 				{
14632 					if (isanumber(newstr))
14633 					{
14634 						value = figureunits(newstr, VTUNITSIND,
14635 							(us_electricalunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH);
14636 						us_setfloatvariablevalue(ni->geom, sch_inductancekey, unitvar, value);
14637 					} else
14638 					{
14639 						TDCLEAR(descript);   defaulttextdescript(descript, ni->geom);  TDSETOFF(descript, 0, 0);
14640 						us_setvariablevalue(ni->geom, sch_inductancekey, newstr, VDISPLAY, descript);
14641 					}
14642 				}
14643 			}
14644 
14645 			/* update black-box function if it changed */
14646 			if (np == sch_bboxprim)
14647 			{
14648 				newstr = getText(DGIN_SPECIAL1);
14649 				if (namesame(newstr, initialeditfield) != 0)
14650 					us_setvariablevalue(ni->geom, sch_functionkey, newstr, VSTRING|VDISPLAY, 0);
14651 			}
14652 
14653 			/* update flip-flop type if it changed */
14654 			if (np == sch_ffprim)
14655 			{
14656 				newbits = ni->userbits & ~NTECHBITS;
14657 				switch (getPopupEntry(DGIN_SPECIAL2))
14658 				{
14659 					case 0:  newbits |= FFTYPERS | FFCLOCKMS;   break;
14660 					case 1:  newbits |= FFTYPEJK | FFCLOCKMS;   break;
14661 					case 2:  newbits |= FFTYPED  | FFCLOCKMS;   break;
14662 					case 3:  newbits |= FFTYPET  | FFCLOCKMS;   break;
14663 					case 4:  newbits |= FFTYPERS | FFCLOCKP;    break;
14664 					case 5:  newbits |= FFTYPEJK | FFCLOCKP;    break;
14665 					case 6:  newbits |= FFTYPED  | FFCLOCKP;    break;
14666 					case 7:  newbits |= FFTYPET  | FFCLOCKP;    break;
14667 					case 8:  newbits |= FFTYPERS | FFCLOCKN;    break;
14668 					case 9:  newbits |= FFTYPEJK | FFCLOCKN;    break;
14669 					case 10: newbits |= FFTYPED  | FFCLOCKN;    break;
14670 					case 11: newbits |= FFTYPET  | FFCLOCKN;    break;
14671 				}
14672 				(void)setval((INTBIG)ni, VNODEINST, x_("userbits"), newbits, VINTEGER);
14673 			}
14674 
14675 			/* update global name/type if it changed */
14676 			if (np == sch_globalprim)
14677 			{
14678 				newstr = getText(DGIN_SPECIAL1);
14679 				i = getPopupEntry(DGIN_SPECIAL2);
14680 				newbits = (ni->userbits & ~NTECHBITS) |
14681 					(((us_exportcharlist[i] >> STATEBITSSH) << NTECHBITSSH) & NTECHBITS);
14682 				(void)setval((INTBIG)ni, VNODEINST, x_("userbits"), newbits, VINTEGER);
14683 				if (namesame(newstr, initialeditfield) != 0)
14684 					(void)setvalkey((INTBIG)ni, VNODEINST, sch_globalnamekey, (INTBIG)newstr,
14685 						VSTRING|VDISPLAY);
14686 			}
14687 
14688 			/* update width of scalable layout transistors if it changed */
14689 			if (np == mocmos_scalablentransprim || np == mocmos_scalableptransprim)
14690 			{
14691 				newstr = getText(DGIN_SPECIAL1);
14692 				if (namesame(newstr, initialeditfield) != 0)
14693 				{
14694 					/* set width on transistor */
14695 					getsimpletype(newstr, &newtype, &newaddr, 0);
14696 					newtype |= VDISPLAY;
14697 					var = setvalkey((INTBIG)ni, VNODEINST, el_attrkey_width, newaddr, newtype);
14698 					if (var != NOVARIABLE)
14699 						TDSETDISPPART(var->textdescript, VTDISPLAYNAMEVALUE);
14700 				}
14701 			}
14702 
14703 			/* update color if it changed */
14704 			if (np->primindex != 0 && np->tech == art_tech && !techedrel)
14705 			{
14706 				i = getPopupEntry(DGIN_SPECIAL2);
14707 				if (us_colorvaluelist[i] == BLACK)
14708 				{
14709 					var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, art_colorkey);
14710 					if (var != NOVARIABLE)
14711 						(void)delvalkey((INTBIG)ni, VNODEINST, art_colorkey);
14712 				} else
14713 				{
14714 					setvalkey((INTBIG)ni, VNODEINST, art_colorkey, us_colorvaluelist[i], VINTEGER);
14715 				}
14716 			}
14717 
14718 			/* update ease of selection if changed */
14719 			if (getControl(DGIN_EASYSELECT) != 0) ni->userbits &= ~HARDSELECTN; else
14720 				ni->userbits |= HARDSELECTN;
14721 
14722 			/* update expansion bit if changed */
14723 			if (np->primindex == 0)
14724 			{
14725 				i = ni->userbits;
14726 				if (getControl(DGIN_EXPANDED) != 0) i |= NEXPAND; else
14727 					i &= ~NEXPAND;
14728 				if (i != (INTBIG)ni->userbits)
14729 					ni->userbits = i;
14730 			}
14731 
14732 			/* update name if it changed */
14733 			newstr = getText(DGIN_NAME);
14734 			while (*newstr == ' ') newstr++;
14735 			if (estrcmp(newstr, namestr) != 0)
14736 			{
14737 				/* change the name of the nodeinst */
14738 				if (*newstr == 0)
14739 					(void)delvalkey((INTBIG)ni, VNODEINST, el_node_name_key); else
14740 				{
14741 					var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
14742 					if (var != NOVARIABLE)
14743 					{
14744 						TDCOPY(descript, var->textdescript);
14745 					} else
14746 					{
14747 						TDCLEAR(descript);
14748 						defaulttextdescript(descript, ni->geom);
14749 					}
14750 					var = setvalkey((INTBIG)ni, VNODEINST, el_node_name_key, (INTBIG)newstr, VSTRING|VDISPLAY);
14751 					if (var != NOVARIABLE)
14752 					{
14753 						TDCOPY(var->textdescript, descript);
14754 						defaulttextsize(3, var->textdescript);
14755 					}
14756 
14757 					/* shift text down if on a cell instance */
14758 					if (var != NOVARIABLE && np->primindex == 0)
14759 					{
14760 						us_setdescriptoffset(var->textdescript,
14761 							0, (ni->highy-ni->lowy) / el_curlib->lambda[el_curtech->techindex]);
14762 					}
14763 				}
14764 			}
14765 
14766 			/* update the circle degrees if it changed */
14767 			if (np == art_circleprim || np == art_thickcircleprim)
14768 			{
14769 				str = getText(DGIN_SPECIAL1_L);
14770 				if (estrcmp(str, _("Degrees of circle:")) == 0)
14771 				{
14772 					newend = eatof(getText(DGIN_SPECIAL1));
14773 					if (newend == 360.0) newend = 0.0;
14774 					newend = newend * EPI / 180.0;
14775 					if (newend != endangle)
14776 						setarcdegrees(ni, startoffset, newend);
14777 				} else
14778 				{
14779 					str = getText(DGIN_SPECIAL1);
14780 					while (*str == ' ' || *str == '\t') str++;
14781 					newstart = eatof(str);
14782 					while (*str != 0 && *str != '/') str++;
14783 					if (*str == 0)
14784 					{
14785 						newend = newstart;
14786 						newstart = 0.0;
14787 					} else
14788 					{
14789 						str++;
14790 						while (*str == ' ' || *str == '\t') str++;
14791 						newend = eatof(str);
14792 					}
14793 
14794 					if (newend == 360.0) newend = newstart = 0.0;
14795 					newend = newend * EPI / 180.0;
14796 					newstart = newstart * EPI / 180.0;
14797 					if (newend != endangle || newstart != startoffset)
14798 						setarcdegrees(ni, newstart, newend);
14799 				}
14800 			}
14801 			endobjectchange((INTBIG)ni, VNODEINST);
14802 
14803 			/* update parameters if they changed */
14804 			for(i=0; i<paramcount; i++)
14805 			{
14806 				var = NOVARIABLE;
14807 				for(j=0; j<ni->numvar; j++)
14808 				{
14809 					var = &ni->firstvar[j];
14810 					if (namesame(paramname[i], truevariablename(var)) == 0) break;
14811 				}
14812 				if (j < ni->numvar)
14813 				{
14814 					/* see if the value changed */
14815 					type = var->type;
14816 					if (estrcmp(paramvalue[i], describevariable(var, -1, -1)) == 0 &&
14817 						(type&(VCODE1|VCODE2)) == paramlanguage[i]) continue;
14818 					type = (type & ~(VCODE1|VCODE2)) | paramlanguage[i];
14819 					if ((type&VDISPLAY) == 0)
14820 					{
14821 						type |= VDISPLAY;
14822 						TDSETDISPPART(var->textdescript, VTDISPLAYNAMEVALUE);
14823 					}
14824 					us_setvariablevalue(ni->geom, var->key, paramvalue[i], type, var->textdescript);
14825 				} else
14826 				{
14827 					/* parameter not there: see if default value was changed */
14828 					if (np->primindex == 0)
14829 					{
14830 						len = estrlen(paramvalue[i]);
14831 						dlen = estrlen(PARAMDEFAULTSTRING);
14832 						if (len < dlen || estrcmp(&paramvalue[i][len-dlen], PARAMDEFAULTSTRING) != 0)
14833 						{
14834 							getsimpletype(paramvalue[i], &type, &addr, 0);
14835 							if ((paramlanguage[i]&(VCODE1|VCODE2)) != 0)
14836 							{
14837 								type = (type & ~(VCODE1|VCODE2)) | paramlanguage[i];
14838 								addr = (INTBIG)paramvalue[i];
14839 							}
14840 							infstr = initinfstr();
14841 							formatinfstr(infstr, x_("ATTR_%s"), paramname[i]);
14842 							us_addparameter(ni, makekey(returninfstr(infstr)), addr, type, 0);
14843 						}
14844 					}
14845 				}
14846 			}
14847 
14848 			/* update attributes if they changed */
14849 			for(i=0; i<attrcount; i++)
14850 			{
14851 				var = NOVARIABLE;
14852 				for(j=0; j<ni->numvar; j++)
14853 				{
14854 					var = &ni->firstvar[j];
14855 					if (namesame(attrname[i], truevariablename(var)) == 0) break;
14856 				}
14857 				if (j < ni->numvar)
14858 				{
14859 					/* see if the value changed */
14860 					type = var->type;
14861 					if (estrcmp(attrvalue[i], describevariable(var, -1, -1)) == 0 &&
14862 						(type&(VCODE1|VCODE2)) == attrlanguage[i]) continue;
14863 					type = (type & ~(VCODE1|VCODE2)) | attrlanguage[i];
14864 					if ((type&VDISPLAY) == 0)
14865 					{
14866 						type |= VDISPLAY;
14867 						TDSETDISPPART(var->textdescript, VTDISPLAYNAMEVALUE);
14868 					}
14869 					us_setvariablevalue(ni->geom, var->key, attrvalue[i], type, var->textdescript);
14870 				}
14871 			}
14872 			us_pophighlight(TRUE);
14873 			us_endchanges(NOWINDOWPART);
14874 			us_state |= HIGHLIGHTSET;
14875 			us_showallhighlight();
14876 			flushscreen();
14877 			makingchanges = FALSE;
14878 		}
14879 
14880 		if (itemHit == DGIN_OK || itemHit == DGIN_CLOSE)
14881 		{
14882 			hide();
14883 		}
14884 		return;
14885 	}
14886 }
14887 
14888 /*
14889  * routine to display information about port prototype "pp" on nodeinst "ni".
14890  * If the port prototype's "temp1" is nonzero, this port has already been
14891  * mentioned and should not be done again.
14892  */
chatportproto(PORTPROTO * pp,PORTPROTO * selected,INTBIG lineno)14893 INTBIG EDiaShowNode::chatportproto(PORTPROTO *pp, PORTPROTO *selected, INTBIG lineno)
14894 {
14895 	REGISTER PORTARCINST *pi;
14896 	REGISTER PORTEXPINST *pe;
14897 	REGISTER ARCINST *ai;
14898 	REGISTER ARCPROTO *ap;
14899 	REGISTER INTBIG i, count, moreinfo, lambda;
14900 	REGISTER CHAR *activity;
14901 	CHAR line[256];
14902 	REGISTER void *infstr;
14903 
14904 	/* talk about the port prototype */
14905 	lambda = lambdaofnode(ni);
14906 	infstr = initinfstr();
14907 	activity = describeportbits(pp->userbits);
14908 	if (*activity != 0)
14909 	{
14910 		formatinfstr(infstr, _("%s port %s connects to"), activity, pp->protoname);
14911 	} else
14912 	{
14913 		formatinfstr(infstr, _("Port %s connects to"), pp->protoname);
14914 	}
14915 	count = 0;
14916 	for(i=0; pp->connects[i] != NOARCPROTO; i++)
14917 	{
14918 		ap = pp->connects[i];
14919 		if ((ni->proto->primindex == 0 || ni->proto->tech != gen_tech) &&
14920 			ap->tech == gen_tech) continue;
14921 		if (count > 0) addstringtoinfstr(infstr, x_(","));
14922 		addstringtoinfstr(infstr, x_(" "));
14923 		addstringtoinfstr(infstr, ap->protoname);
14924 		count++;
14925 	}
14926 	moreinfo = 0;
14927 	if (pp == selected) moreinfo = 1;
14928 	for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
14929 		if (pi->proto == pp) moreinfo = 1;
14930 	for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
14931 		if (pe->proto == pp) moreinfo = 1;
14932 	if (moreinfo != 0) addstringtoinfstr(infstr, x_(":"));
14933 	stuffLine(DGIN_CONLIST, returninfstr(infstr));
14934 	lineno++;
14935 
14936 	/* mention if it is highlighted */
14937 	if (pp == selected)
14938 	{
14939 		stuffLine(DGIN_CONLIST, _("  Highlighted port"));
14940 		lineno++;
14941 	}
14942 
14943 	/* talk about any arcs on this prototype */
14944 	for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
14945 	{
14946 		if (pi->proto != pp) continue;
14947 		ai = pi->conarcinst;
14948 		if (ai->end[0].portarcinst == pi) i = 0; else i = 1;
14949 		(void)esnprintf(line, 256, _("  Connected at (%s,%s) to %s arc"), latoa(ai->end[i].xpos, lambda),
14950 			latoa(ai->end[i].ypos, lambda), describearcinst(ai));
14951 		ai->temp2 = lineno;
14952 		stuffLine(DGIN_CONLIST, line);
14953 		lineno++;
14954 	}
14955 
14956 	/* talk about any exports of this prototype */
14957 	for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
14958 	{
14959 		if (pe->proto != pp) continue;
14960 		infstr = initinfstr();
14961 		formatinfstr(infstr, _("  Available as %s export '%s'"), describeportbits(pe->exportproto->userbits),
14962 			pe->exportproto->protoname);
14963 		stuffLine(DGIN_CONLIST, returninfstr(infstr));
14964 		pe->exportproto->temp2 = lineno;
14965 		lineno++;
14966 	}
14967 	return(lineno);
14968 }
14969 
14970 /****************************** SCALABLE TRANSISTOR DIALOG ******************************/
14971 
14972 /* Scalable Transistors */
14973 static DIALOGITEM us_scatrndialogitems[] =
14974 {
14975  /*  1 */ {0, {128,212,152,292}, BUTTON, N_("OK")},
14976  /*  2 */ {0, {128,12,152,92}, BUTTON, N_("Cancel")},
14977  /*  3 */ {0, {128,112,152,192}, BUTTON, N_("More")},
14978  /*  4 */ {0, {8,8,24,152}, MESSAGE, N_("Number of contacts:")},
14979  /*  5 */ {0, {8,157,24,209}, POPUP, x_("")},
14980  /*  6 */ {0, {32,8,48,292}, CHECK, N_("Move contacts half-lambda closer in")},
14981  /*  7 */ {0, {80,8,96,152}, MESSAGE, N_("Actual width:")},
14982  /*  8 */ {0, {80,156,96,292}, EDITTEXT, x_("")},
14983  /*  9 */ {0, {56,8,72,152}, MESSAGE, N_("Maximum width:")},
14984  /* 10 */ {0, {56,156,72,292}, MESSAGE, x_("")},
14985  /* 11 */ {0, {104,156,120,292}, MESSAGE, x_("")},
14986  /* 12 */ {0, {104,8,120,152}, MESSAGE, x_("")}
14987 };
14988 static DIALOG us_scatrndialog = {{75,75,236,376}, N_("Scalable Transistor Information"), 0, 12, us_scatrndialogitems, 0, 0};
14989 
14990 /* special items for the "global signal" dialog: */
14991 #define DSCT_MORE            3		/* More button (button) */
14992 #define DSCT_NUMCONTACTS     5		/* Number of contacts (popup) */
14993 #define DSCT_INSETCONTACTS   6		/* Inset contacts (check) */
14994 #define DSCT_ACTUALWID       8		/* Actual width of transistor (edit text) */
14995 #define DSCT_MAXIMUMWID     10		/* Maximum width of transistor (stat text) */
14996 #define DSCT_ACTUALEVAL     11		/* Evaluation of actual width (stat text) */
14997 #define DSCT_ACTUALEVAL_L   12		/* Label for evaluation value (stat text) */
14998 
us_scalabletransdlog(void)14999 INTBIG us_scalabletransdlog(void)
15000 {
15001 	CHAR *pt, *origactualwidth, *origvarstring, newvarstring[20];
15002 	REGISTER INTBIG itemHit, lambda, numcontacts, xsize, widlang;
15003 	INTBIG plx, ply, phx, phy;
15004 	REGISTER BOOLEAN insetcontacts, changed;
15005 	REGISTER NODEINST *ni;
15006 	REGISTER VARIABLE *var;
15007 	REGISTER void *dia;
15008 	static CHAR *contcount[3] = {x_("0"), x_("1"), x_("2")};
15009 
15010 	/* see what is highlighted */
15011 	ni = (NODEINST *)us_getobject(VNODEINST, TRUE);
15012 	if (ni == NONODEINST) return(0);
15013 
15014 	/* see if there is a global signal name already on it */
15015 	dia = DiaInitDialog(&us_scatrndialog);
15016 	if (dia == 0) return(0);
15017 	DiaSetPopup(dia, DSCT_NUMCONTACTS, 3, contcount);
15018 	numcontacts = 2;
15019 	insetcontacts = FALSE;
15020 	var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, mocmos_transcontactkey);
15021 	if (var == NOVARIABLE) origvarstring = x_("2"); else
15022 		origvarstring = (CHAR *)var->addr;
15023 	if (*origvarstring == '0' || *origvarstring == '1' || *origvarstring == '2')
15024 	{
15025 		numcontacts = *origvarstring - '0';
15026 		origvarstring++;
15027 	}
15028 	if (*origvarstring == 'i' || *origvarstring == 'I') insetcontacts = TRUE;
15029 	DiaSetPopupEntry(dia, DSCT_NUMCONTACTS, numcontacts);
15030 	if (insetcontacts) DiaSetControl(dia, DSCT_INSETCONTACTS, 1);
15031 
15032 	/* load width information */
15033 	nodesizeoffset(ni, &plx, &ply, &phx, &phy);
15034 	lambda = lambdaofnode(ni);
15035 	xsize = ni->highx - ni->lowx - plx - phx;
15036 	origactualwidth = latoa(xsize, lambda);
15037 	DiaSetText(dia, DSCT_MAXIMUMWID, origactualwidth);
15038 	widlang = 0;
15039 	var = getvalkeynoeval((INTBIG)ni, VNODEINST, -1, el_attrkey_width);
15040 	if (var != NOVARIABLE)
15041 	{
15042 		widlang = var->type & (VCODE1|VCODE2);
15043 		origactualwidth = describevariable(var, -1, -1);
15044 		if (widlang != 0)
15045 		{
15046 			var = getvalkey((INTBIG)ni, VNODEINST, -1, el_attrkey_width);
15047 			DiaSetText(dia, DSCT_ACTUALEVAL_L, _("Evaluation:"));
15048 			DiaSetText(dia, DSCT_ACTUALEVAL, describevariable(var, -1, -1));
15049 		}
15050 	}
15051 	DiaSetText(dia, DSCT_ACTUALWID, origactualwidth);
15052 
15053 	for(;;)
15054 	{
15055 		itemHit = DiaNextHit(dia);
15056 		if (itemHit == OK || itemHit == CANCEL || itemHit == DSCT_MORE) break;
15057 		if (itemHit == DSCT_INSETCONTACTS)
15058 		{
15059 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
15060 			continue;
15061 		}
15062 	}
15063 
15064 	if (itemHit != CANCEL)
15065 	{
15066 		numcontacts = DiaGetPopupEntry(dia, DSCT_NUMCONTACTS);
15067 		if (DiaGetControl(dia, DSCT_INSETCONTACTS) != 0) insetcontacts = TRUE; else
15068 			insetcontacts = FALSE;
15069 		esnprintf(newvarstring, 20, x_("%ld"), numcontacts);
15070 		if (insetcontacts) estrcat(newvarstring, x_("I"));
15071 		pt = DiaGetText(dia, DSCT_ACTUALWID);
15072 		if (namesame(pt, origactualwidth) != 0 || namesame(newvarstring, origvarstring) != 0)
15073 			changed = TRUE; else changed = FALSE;
15074 		if (changed)
15075 		{
15076 			us_pushhighlight();
15077 			us_clearhighlightcount();
15078 			startobjectchange((INTBIG)ni, VNODEINST);
15079 			if (namesame(newvarstring, origvarstring) != 0)
15080 				setvalkey((INTBIG)ni, VNODEINST, mocmos_transcontactkey, (INTBIG)newvarstring, VSTRING);
15081 			if (namesame(pt, origactualwidth) != 0)
15082 			{
15083 				var = setvalkey((INTBIG)ni, VNODEINST, el_attrkey_width, (INTBIG)pt, VSTRING|VDISPLAY|widlang);
15084 				if (var != NOVARIABLE)
15085 					TDSETDISPPART(var->textdescript, VTDISPLAYNAMEVALUE);
15086 			}
15087 			endobjectchange((INTBIG)ni, VNODEINST);
15088 			us_pophighlight(TRUE);
15089 		}
15090 	}
15091 	DiaDoneDialog(dia);
15092 
15093 	if (itemHit == DSCT_MORE)
15094 	{
15095 		/* get info on node */
15096 		us_endchanges(NOWINDOWPART);
15097 		(void)us_showdlog(FALSE);
15098 	}
15099 	return(0);
15100 }
15101 
15102 /****************************** GLOBAL SIGNAL DIALOG ******************************/
15103 
15104 /* Global Signal */
15105 static DIALOGITEM us_globdialogitems[] =
15106 {
15107  /*  1 */ {0, {100,196,124,276}, BUTTON, N_("OK")},
15108  /*  2 */ {0, {100,12,124,92}, BUTTON, N_("Cancel")},
15109  /*  3 */ {0, {8,8,24,172}, MESSAGE, N_("Global signal name:")},
15110  /*  4 */ {0, {32,8,48,280}, EDITTEXT, x_("")},
15111  /*  5 */ {0, {64,8,80,140}, MESSAGE, N_("Characteristics:")},
15112  /*  6 */ {0, {64,144,80,284}, POPUP, x_("")},
15113  /*  7 */ {0, {100,104,124,184}, BUTTON, N_("More")}
15114 };
15115 static DIALOG us_globdialog = {{75,75,208,368}, N_("Global Signal"), 0, 7, us_globdialogitems, 0, 0};
15116 
15117 /* special items for the "global signal" dialog: */
15118 #define DGLO_SIGNAME         4		/* Signal name (edit text) */
15119 #define DGLO_CHARACTERISTICS 6		/* Characteristics (popup) */
15120 #define DGLO_MORE            7		/* More information (button) */
15121 
us_globalsignaldlog(void)15122 INTBIG us_globalsignaldlog(void)
15123 {
15124 	CHAR *newlang[NUMPORTCHARS], *newsigname;
15125 	REGISTER INTBIG i, itemHit;
15126 	REGISTER UINTBIG characteristic;
15127 	REGISTER NODEINST *ni;
15128 	REGISTER VARIABLE *var;
15129 	REGISTER void *dia;
15130 
15131 	/* see what is highlighted */
15132 	ni = (NODEINST *)us_getobject(VNODEINST, TRUE);
15133 	if (ni == NONODEINST) return(0);
15134 	if (ni->proto != sch_globalprim) return(0);
15135 
15136 	/* see if there is a global signal name already on it */
15137 	var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, sch_globalnamekey);
15138 	if (var == NOVARIABLE) us_globdialog.items = 6; else
15139 		us_globdialog.items = 7;
15140 	dia = DiaInitDialog(&us_globdialog);
15141 	if (dia == 0) return(0);
15142 
15143 	for(i=0; i<NUMPORTCHARS; i++) newlang[i] = TRANSLATE(us_exportcharnames[i]);
15144 	DiaSetPopup(dia, DGLO_CHARACTERISTICS, NUMPORTCHARS, newlang);
15145 	characteristic = ((ni->userbits&NTECHBITS) >> NTECHBITSSH) << STATEBITSSH;
15146 	for(i=0; i<NUMPORTCHARS; i++)
15147 		if (us_exportcharlist[i] == characteristic)
15148 	{
15149 		DiaSetPopupEntry(dia, DGLO_CHARACTERISTICS, i);
15150 		break;
15151 	}
15152 	if (var != NOVARIABLE)
15153 		DiaSetText(dia, DGLO_SIGNAME, (CHAR *)var->addr);
15154 
15155 	for(;;)
15156 	{
15157 		itemHit = DiaNextHit(dia);
15158 		if (itemHit == OK || itemHit == CANCEL || itemHit == DGLO_MORE) break;
15159 	}
15160 
15161 	if (itemHit == CANCEL) newsigname = 0; else
15162 	{
15163 		newsigname = DiaGetText(dia, DGLO_SIGNAME);
15164 		(void)setvalkey((INTBIG)ni, VNODEINST, sch_globalnamekey, (INTBIG)newsigname, VSTRING|VDISPLAY);
15165 		i = DiaGetPopupEntry(dia, DGLO_CHARACTERISTICS);
15166 		ni->userbits = (ni->userbits & ~NTECHBITS) |
15167 			(((us_exportcharlist[i] >> STATEBITSSH) << NTECHBITSSH) & NTECHBITS);
15168 	}
15169 	DiaDoneDialog(dia);
15170 
15171 	if (itemHit == DGLO_MORE)
15172 	{
15173 		/* get info on node */
15174 		us_endchanges(NOWINDOWPART);
15175 		(void)us_showdlog(FALSE);
15176 	}
15177 	return(0);
15178 }
15179 
15180 /****************************** GRID OPTIONS DIALOG ******************************/
15181 
15182 /* Grid options */
15183 static DIALOGITEM us_griddialogitems[] =
15184 {
15185  /*  1 */ {0, {116,384,140,448}, BUTTON, N_("OK")},
15186  /*  2 */ {0, {116,12,140,76}, BUTTON, N_("Cancel")},
15187  /*  3 */ {0, {32,8,48,269}, MESSAGE, N_("Grid dot spacing (current window):")},
15188  /*  4 */ {0, {32,272,48,352}, EDITTEXT, x_("")},
15189  /*  5 */ {0, {8,272,24,366}, MESSAGE, N_("Horizontal:")},
15190  /*  6 */ {0, {32,372,48,452}, EDITTEXT, x_("")},
15191  /*  7 */ {0, {60,8,76,269}, MESSAGE, N_("Default grid spacing (new windows):")},
15192  /*  8 */ {0, {60,272,76,352}, EDITTEXT, x_("")},
15193  /*  9 */ {0, {8,372,24,466}, MESSAGE, N_("Vertical:")},
15194  /* 10 */ {0, {60,372,76,452}, EDITTEXT, x_("")},
15195  /* 11 */ {0, {88,8,104,269}, MESSAGE, N_("Distance between bold dots:")},
15196  /* 12 */ {0, {88,272,104,352}, EDITTEXT, x_("")},
15197  /* 13 */ {0, {120,132,136,329}, CHECK, N_("Align grid with circuitry")},
15198  /* 14 */ {0, {88,372,104,452}, EDITTEXT, x_("")}
15199 };
15200 static DIALOG us_griddialog = {{50,75,199,550}, N_("Grid Options"), 0, 14, us_griddialogitems, 0, 0};
15201 
15202 /* special items for the "grid settings" dialog: */
15203 #define DGRD_HORIZSPAC       4		/* Horizontal spacing (edit text) */
15204 #define DGRD_VERTSPAC        6		/* Vertical spacing (edit text) */
15205 #define DGRD_DEFHORIZSPAC    8		/* Default horizontal spacing (edit text) */
15206 #define DGRD_DEFVERTSPAC    10		/* Default vertical spacing (edit text) */
15207 #define DGRD_BOLDHORIZSPAC  12		/* Bold dot horizontal spacing (edit text) */
15208 #define DGRD_ALIGNDOTS      13		/* Align with circuitry (check) */
15209 #define DGRD_BOLDVERTSPAC   14		/* Bold dot vertical spacing (edit text) */
15210 
us_griddlog(void)15211 INTBIG us_griddlog(void)
15212 {
15213 	REGISTER INTBIG itemHit, xspacing, yspacing, xboldspacing, yboldspacing,
15214 		newgridx, newgridy, oldgridfloats, gridfloats;
15215 	INTBIG defgrid[2], bolddots[2];
15216 	REGISTER VARIABLE *var;
15217 	CHAR buf[20];
15218 	REGISTER void *dia;
15219 
15220 	/* display the grid settings dialog box */
15221 	dia = DiaInitDialog(&us_griddialog);
15222 	if (dia == 0) return(0);
15223 	if (el_curwindowpart == NOWINDOWPART || el_curwindowpart->curnodeproto == NONODEPROTO)
15224 	{
15225 		DiaDimItem(dia, DGRD_HORIZSPAC);
15226 		DiaDimItem(dia, DGRD_VERTSPAC);
15227 	} else
15228 	{
15229 		DiaUnDimItem(dia, DGRD_HORIZSPAC);
15230 		DiaUnDimItem(dia, DGRD_VERTSPAC);
15231 		DiaSetText(dia, -DGRD_HORIZSPAC, frtoa(el_curwindowpart->gridx));
15232 		DiaSetText(dia, DGRD_VERTSPAC, frtoa(el_curwindowpart->gridy));
15233 	}
15234 	var = getval((INTBIG)us_tool, VTOOL, VFRACT|VISARRAY, x_("USER_default_grid"));
15235 	if (var == NOVARIABLE) xspacing = yspacing = WHOLE; else
15236 	{
15237 		xspacing = ((INTBIG *)var->addr)[0];
15238 		yspacing = ((INTBIG *)var->addr)[1];
15239 	}
15240 	DiaSetText(dia, DGRD_DEFHORIZSPAC, frtoa(xspacing));
15241 	DiaSetText(dia, DGRD_DEFVERTSPAC, frtoa(yspacing));
15242 
15243 	var = getvalkey((INTBIG)us_tool, VTOOL, -1, us_gridboldspacingkey);
15244 	if (var == NOVARIABLE) xboldspacing = yboldspacing = 10; else
15245 	{
15246 		if ((var->type&VISARRAY) == 0)
15247 			xboldspacing = yboldspacing = var->addr; else
15248 		{
15249 			xboldspacing = ((INTBIG *)var->addr)[0];
15250 			yboldspacing = ((INTBIG *)var->addr)[1];
15251 		}
15252 	}
15253 	esnprintf(buf, 20, x_("%ld"), xboldspacing);   DiaSetText(dia, DGRD_BOLDHORIZSPAC, buf);
15254 	esnprintf(buf, 20, x_("%ld"), yboldspacing);   DiaSetText(dia, DGRD_BOLDVERTSPAC, buf);
15255 
15256 	oldgridfloats = 0;
15257 	var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_gridfloatskey);
15258 	if (var != NOVARIABLE && var->addr != 0) oldgridfloats = 1;
15259 	DiaSetControl(dia, DGRD_ALIGNDOTS, oldgridfloats);
15260 
15261 	/* loop until done */
15262 	for(;;)
15263 	{
15264 		itemHit = DiaNextHit(dia);
15265 		if (itemHit == OK || itemHit == CANCEL) break;
15266 		if (itemHit == DGRD_ALIGNDOTS)
15267 		{
15268 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
15269 			continue;
15270 		}
15271 	}
15272 
15273 	if (itemHit != CANCEL)
15274 	{
15275 		/* change window-independent grid options */
15276 		defgrid[0] = atofr(DiaGetText(dia, DGRD_DEFHORIZSPAC));
15277 		defgrid[1] = atofr(DiaGetText(dia, DGRD_DEFVERTSPAC));
15278 		if (defgrid[0] != xspacing || defgrid[1] != yspacing)
15279 			(void)setval((INTBIG)us_tool, VTOOL, x_("USER_default_grid"),
15280 				(INTBIG)defgrid, VFRACT|VISARRAY|(2<<VLENGTHSH));
15281 		gridfloats = DiaGetControl(dia, DGRD_ALIGNDOTS);
15282 		bolddots[0] = eatoi(DiaGetText(dia, DGRD_BOLDHORIZSPAC));
15283 		bolddots[1] = eatoi(DiaGetText(dia, DGRD_BOLDVERTSPAC));
15284 
15285 		/* see if grid changed in this cell */
15286 		if (el_curwindowpart != NOWINDOWPART && el_curwindowpart->curnodeproto != NONODEPROTO)
15287 		{
15288 			newgridx = atofr(DiaGetText(dia, DGRD_HORIZSPAC));
15289 			newgridy = atofr(DiaGetText(dia, DGRD_VERTSPAC));
15290 			if (newgridx != el_curwindowpart->gridx || newgridy != el_curwindowpart->gridy ||
15291 				bolddots[0] != xboldspacing || bolddots[1] != yboldspacing ||
15292 				gridfloats != oldgridfloats)
15293 			{
15294 				/* adjust grid in current window */
15295 				us_pushhighlight();
15296 				us_clearhighlightcount();
15297 				startobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
15298 
15299 				/* turn grid off if on */
15300 				if ((el_curwindowpart->state&GRIDON) != 0)
15301 					(void)setval((INTBIG)el_curwindowpart, VWINDOWPART, x_("state"),
15302 						el_curwindowpart->state & ~GRIDON, VINTEGER);
15303 
15304 				if (newgridx != el_curwindowpart->gridx || newgridy != el_curwindowpart->gridy)
15305 				{
15306 					(void)setval((INTBIG)el_curwindowpart, VWINDOWPART, x_("gridx"), newgridx, VINTEGER);
15307 					(void)setval((INTBIG)el_curwindowpart, VWINDOWPART, x_("gridy"), newgridy, VINTEGER);
15308 				}
15309 				if (bolddots[0] != xboldspacing || bolddots[1] != yboldspacing)
15310 					(void)setvalkey((INTBIG)us_tool, VTOOL, us_gridboldspacingkey,
15311 						(INTBIG)bolddots, VINTEGER|VISARRAY|(2<<VLENGTHSH));
15312 				if (gridfloats != oldgridfloats)
15313 					(void)setvalkey((INTBIG)us_tool, VTOOL, us_gridfloatskey,
15314 						(INTBIG)gridfloats, VINTEGER);
15315 
15316 				/* show new grid */
15317 				us_gridset(el_curwindowpart, GRIDON);
15318 
15319 				/* restore highlighting */
15320 				endobjectchange((INTBIG)el_curwindowpart, VWINDOWPART);
15321 				us_pophighlight(FALSE);
15322 			}
15323 		} else
15324 		{
15325 			/* no current window, but save grid information if it changed */
15326 			if (bolddots[0] != xboldspacing || bolddots[1] != yboldspacing)
15327 				(void)setvalkey((INTBIG)us_tool, VTOOL, us_gridboldspacingkey,
15328 					(INTBIG)bolddots, VINTEGER|VISARRAY|(2<<VLENGTHSH));
15329 			if (gridfloats != oldgridfloats)
15330 				(void)setvalkey((INTBIG)us_tool, VTOOL, us_gridfloatskey,
15331 					(INTBIG)gridfloats, VINTEGER);
15332 		}
15333 
15334 	}
15335 	DiaDoneDialog(dia);
15336 	return(0);
15337 }
15338 
15339 /****************************** HELP DIALOG ******************************/
15340 
15341 /* Help */
15342 static DIALOGITEM us_helpdialogitems[] =
15343 {
15344  /*  1 */ {0, {288,376,312,440}, BUTTON, N_("OK")},
15345  /*  2 */ {0, {8,32,24,91}, MESSAGE, N_("Topics:")},
15346  /*  3 */ {0, {8,192,280,636}, SCROLL, x_("")},
15347  /*  4 */ {0, {24,8,309,177}, SCROLL, x_("")}
15348 };
15349 static DIALOG us_helpdialog = {{50,75,378,720}, N_("Help"), 0, 4, us_helpdialogitems, 0, 0};
15350 
15351 /* special items for the "help" dialog: */
15352 #define DHLP_HELP     3		/* help (scroll) */
15353 #define DHLP_TOPICS   4		/* topics (scroll) */
15354 
us_helpdlog(CHAR * prompt)15355 INTBIG us_helpdlog(CHAR *prompt)
15356 {
15357 	CHAR *filename, *line, buf[256], *platform, *pt;
15358 	INTBIG itemHit, i;
15359 	FILE *in;
15360 	REGISTER VARIABLE *var;
15361 	REGISTER void *infstr;
15362 	REGISTER void *dia;
15363 
15364 	/* get the help file */
15365 	infstr = initinfstr();
15366 	addstringtoinfstr(infstr, el_libdir);
15367 	addstringtoinfstr(infstr, prompt);
15368 	line = returninfstr(infstr);
15369 	in = xopen(line, us_filetypehelp, x_(""), &filename);
15370 	if (in == NULL)
15371 	{
15372 		us_abortcommand(_("Cannot find help file: %s"), line);
15373 		return(0);
15374 	}
15375 
15376 	/* show the "help" dialog */
15377 	dia = DiaInitDialog(&us_helpdialog);
15378 	if (dia == 0)
15379 	{
15380 		xclose(in);
15381 		return(0);
15382 	}
15383 	DiaInitTextDialog(dia, DHLP_HELP, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
15384 		SCHORIZBAR|SCSMALLFONT|SCFIXEDWIDTH);
15385 	DiaInitTextDialog(dia, DHLP_TOPICS, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
15386 		SCSELMOUSE|SCSELKEY|SCREPORT|SCSMALLFONT);
15387 
15388 	/* determine the platform that is running */
15389 	var = getval((INTBIG)us_tool, VTOOL, VSTRING, x_("USER_machine"));
15390 	if (var == NOVARIABLE) platform = x_(""); else
15391 		platform = (CHAR *)var->addr;
15392 
15393 	/* load the topics list */
15394 	for(;;)
15395 	{
15396 		if (xfgets(buf, 256, in)) break;
15397 		if (buf[0] != '!') continue;
15398 		for(pt = buf; *pt != 0; pt++)
15399 			if (*pt == '[') break;
15400 		if (*pt == '[')
15401 		{
15402 			*pt++ = 0;
15403 			if (namesamen(pt, platform, estrlen(platform)) != 0) continue;
15404 		}
15405 		DiaStuffLine(dia, DHLP_TOPICS, &buf[1]);
15406 	}
15407 	DiaSelectLine(dia, DHLP_TOPICS, -1);
15408 
15409 	for(;;)
15410 	{
15411 		itemHit = DiaNextHit(dia);
15412 		if (itemHit == OK) break;
15413 		if (itemHit == DHLP_TOPICS)
15414 		{
15415 			line = DiaGetScrollLine(dia, DHLP_TOPICS, DiaGetCurLine(dia, DHLP_TOPICS));
15416 			xseek(in, 0, 0);
15417 			DiaLoadTextDialog(dia, DHLP_HELP, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
15418 			for(;;)
15419 			{
15420 				if (xfgets(buf, 256, in)) break;
15421 				if (buf[0] != '!') continue;
15422 				for(pt = buf; *pt != 0; pt++)
15423 					if (*pt == '[') break;
15424 				if (*pt == '[')
15425 				{
15426 					*pt++ = 0;
15427 					if (namesamen(pt, platform, estrlen(platform)) != 0) continue;
15428 				}
15429 				if (estrcmp(&buf[1], line) == 0) break;
15430 			}
15431 			for(i=0; ; i++)
15432 			{
15433 				if (xfgets(buf, 256, in)) break;
15434 				if (buf[0] == '!') break;
15435 				if (buf[0] == 0 && i == 0) continue;
15436 				DiaStuffLine(dia, DHLP_HELP, buf);
15437 			}
15438 			DiaSelectLine(dia, DHLP_HELP, -1);
15439 			continue;
15440 		}
15441 	}
15442 	DiaDoneDialog(dia);
15443 	xclose(in);
15444 	return(0);
15445 }
15446 
15447 /****************************** ICON STYLE DIALOG ******************************/
15448 
15449 /* Icon Options */
15450 static DIALOGITEM us_iconoptdialogitems[] =
15451 {
15452  /*  1 */ {0, {216,309,240,389}, BUTTON, N_("OK")},
15453  /*  2 */ {0, {180,308,204,388}, BUTTON, N_("Cancel")},
15454  /*  3 */ {0, {8,8,24,88}, MESSAGE, N_("Inputs on:")},
15455  /*  4 */ {0, {8,92,24,192}, POPUP, x_("")},
15456  /*  5 */ {0, {32,8,48,88}, MESSAGE, N_("Outputs on:")},
15457  /*  6 */ {0, {32,92,48,192}, POPUP, x_("")},
15458  /*  7 */ {0, {56,8,72,88}, MESSAGE, N_("Bidir. on:")},
15459  /*  8 */ {0, {56,92,72,192}, POPUP, x_("")},
15460  /*  9 */ {0, {8,208,24,288}, MESSAGE, N_("Power on:")},
15461  /* 10 */ {0, {8,292,24,392}, POPUP, x_("")},
15462  /* 11 */ {0, {32,208,48,288}, MESSAGE, N_("Ground on:")},
15463  /* 12 */ {0, {32,292,48,392}, POPUP, x_("")},
15464  /* 13 */ {0, {56,208,72,288}, MESSAGE, N_("Clock on:")},
15465  /* 14 */ {0, {56,292,72,392}, POPUP, x_("")},
15466  /* 15 */ {0, {88,8,104,116}, CHECK, N_("Draw leads")},
15467  /* 16 */ {0, {144,8,160,160}, MESSAGE, N_("Export location:")},
15468  /* 17 */ {0, {144,164,160,264}, POPUP, x_("")},
15469  /* 18 */ {0, {168,8,184,160}, MESSAGE, N_("Export style:")},
15470  /* 19 */ {0, {168,164,184,264}, POPUP, x_("")},
15471  /* 20 */ {0, {112,8,128,116}, CHECK, N_("Draw body")},
15472  /* 21 */ {0, {113,264,129,340}, EDITTEXT, x_("")},
15473  /* 22 */ {0, {192,8,208,160}, MESSAGE, N_("Export technology:")},
15474  /* 23 */ {0, {192,164,208,264}, POPUP, x_("")},
15475  /* 24 */ {0, {252,8,268,184}, MESSAGE, N_("Instance location:")},
15476  /* 25 */ {0, {252,188,268,288}, POPUP, x_("")},
15477  /* 26 */ {0, {224,8,240,184}, CHECK, N_("Reverse export order")},
15478  /* 27 */ {0, {88,148,104,248}, MESSAGE, N_("Lead length:")},
15479  /* 28 */ {0, {88,264,104,340}, EDITTEXT, x_("")},
15480  /* 29 */ {0, {112,148,128,248}, MESSAGE, N_("Lead spacing:")}
15481 };
15482 static DIALOG us_iconoptdialog = {{75,75,352,476}, N_("Icon Options"), 0, 29, us_iconoptdialogitems, 0, 0};
15483 /* special items for the "Icon Style" dialog: */
15484 #define DICO_INPUTLOC        4		/* Input location (popup) */
15485 #define DICO_OUTPUTLOC       6		/* Output location (popup) */
15486 #define DICO_BIDIRLOC        8		/* Bidir location (popup) */
15487 #define DICO_POWERLOC       10		/* Power location (popup) */
15488 #define DICO_GROUNDLOC      12		/* Ground location (popup) */
15489 #define DICO_CLOCKLOC       14		/* Clock location (popup) */
15490 #define DICO_DRAWLEADS      15		/* Draw leads (check) */
15491 #define DICO_PORTLOC        17		/* Port Location (popup) */
15492 #define DICO_PORTSTYLE      19		/* Port Style (popup) */
15493 #define DICO_DRAWBODY       20		/* Draw body (check) */
15494 #define DICO_LEADSPACING    21		/* Lead spacing (edit text) */
15495 #define DICO_EXPORTTECH     23		/* Export technology (popup) */
15496 #define DICO_INSTANCELOC    25		/* Instance location (popup) */
15497 #define DICO_REVEXPORTORD   26		/* Reverse order of exports (check) */
15498 #define DICO_LEADLENGTH     28		/* Lead length (edit text) */
15499 
us_iconstyledlog(void)15500 INTBIG us_iconstyledlog(void)
15501 {
15502 	INTBIG itemHit, style, origstyle, index, i, leadspacing, leadlength;
15503 	REGISTER VARIABLE *var;
15504 	CHAR *newlang[4], line[50];
15505 	REGISTER void *dia;
15506 	static CHAR *location[] = {N_("Left side"), N_("Right side"), N_("Top side"),
15507 		N_("Bottom side")};
15508 	static CHAR *portlocation[] = {N_("Body"), N_("Lead end"), N_("Lead middle")};
15509 	static CHAR *portstyle[] = {N_("Centered"), N_("Inward"), N_("Outward")};
15510 	static CHAR *porttech[] = {N_("Universal"), N_("Schematic")};
15511 	static CHAR *instlocation[] = {N_("Upper-right"), N_("Upper-left"),
15512 		N_("Lower-right"), N_("Lower-left")};
15513 
15514 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_icon_lead_length"));
15515 	if (var != NOVARIABLE) leadlength = var->addr; else leadlength = ICONLEADDEFLEN;
15516 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_icon_lead_spacing"));
15517 	if (var != NOVARIABLE) leadspacing = var->addr; else leadspacing = ICONLEADDEFSEP;
15518 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_icon_style"));
15519 	if (var != NOVARIABLE) style = var->addr; else style = ICONSTYLEDEFAULT;
15520 	origstyle = style;
15521 	dia = DiaInitDialog(&us_iconoptdialog);
15522 	if (dia == 0) return(0);
15523 	esnprintf(line, 50, x_("%ld"), leadlength);
15524 	DiaSetText(dia, DICO_LEADLENGTH, line);
15525 	esnprintf(line, 50, x_("%ld"), leadspacing);
15526 	DiaSetText(dia, DICO_LEADSPACING, line);
15527 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(location[i]);
15528 	DiaSetPopup(dia, DICO_INPUTLOC, 4, newlang);
15529 	index = (style & ICONSTYLESIDEIN) >> ICONSTYLESIDEINSH;
15530 	DiaSetPopupEntry(dia, DICO_INPUTLOC, index);
15531 	DiaSetPopup(dia, DICO_OUTPUTLOC, 4, newlang);
15532 	index = (style & ICONSTYLESIDEOUT) >> ICONSTYLESIDEOUTSH;
15533 	DiaSetPopupEntry(dia, DICO_OUTPUTLOC, index);
15534 	DiaSetPopup(dia, DICO_BIDIRLOC, 4, newlang);
15535 	index = (style & ICONSTYLESIDEBIDIR) >> ICONSTYLESIDEBIDIRSH;
15536 	DiaSetPopupEntry(dia, DICO_BIDIRLOC, index);
15537 	DiaSetPopup(dia, DICO_POWERLOC, 4, newlang);
15538 	index = (style & ICONSTYLESIDEPOWER) >> ICONSTYLESIDEPOWERSH;
15539 	DiaSetPopupEntry(dia, DICO_POWERLOC, index);
15540 	DiaSetPopup(dia, DICO_GROUNDLOC, 4, newlang);
15541 	index = (style & ICONSTYLESIDEGROUND) >> ICONSTYLESIDEGROUNDSH;
15542 	DiaSetPopupEntry(dia, DICO_GROUNDLOC, index);
15543 	DiaSetPopup(dia, DICO_CLOCKLOC, 4, newlang);
15544 	index = (style & ICONSTYLESIDECLOCK) >> ICONSTYLESIDECLOCKSH;
15545 	DiaSetPopupEntry(dia, DICO_CLOCKLOC, index);
15546 
15547 	for(i=0; i<3; i++) newlang[i] = TRANSLATE(portlocation[i]);
15548 	DiaSetPopup(dia, DICO_PORTLOC, 3, newlang);
15549 	index = (style & ICONSTYLEPORTLOC) >> ICONSTYLEPORTLOCSH;
15550 	DiaSetPopupEntry(dia, DICO_PORTLOC, index);
15551 	for(i=0; i<3; i++) newlang[i] = TRANSLATE(portstyle[i]);
15552 	DiaSetPopup(dia, DICO_PORTSTYLE, 3, newlang);
15553 	index = (style & ICONSTYLEPORTSTYLE) >> ICONSTYLEPORTSTYLESH;
15554 	DiaSetPopupEntry(dia, DICO_PORTSTYLE, index);
15555 
15556 	for(i=0; i<2; i++) newlang[i] = TRANSLATE(porttech[i]);
15557 	DiaSetPopup(dia, DICO_EXPORTTECH, 2, newlang);
15558 	index = (style & ICONSTYLETECH) >> ICONSTYLETECHSH;
15559 	DiaSetPopupEntry(dia, DICO_EXPORTTECH, index);
15560 
15561 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(instlocation[i]);
15562 	DiaSetPopup(dia, DICO_INSTANCELOC, 4, newlang);
15563 	index = (style & ICONINSTLOC) >> ICONINSTLOCSH;
15564 	DiaSetPopupEntry(dia, DICO_INSTANCELOC, index);
15565 
15566 	if ((style&ICONSTYLEDRAWNOLEADS) == 0) DiaSetControl(dia, DICO_DRAWLEADS, 1);
15567 	if ((style&ICONSTYLEDRAWNOBODY) == 0) DiaSetControl(dia, DICO_DRAWBODY, 1);
15568 	if ((style&ICONSTYLEREVEXPORT) != 0) DiaSetControl(dia, DICO_REVEXPORTORD, 1);
15569 
15570 	for(;;)
15571 	{
15572 		itemHit = DiaNextHit(dia);
15573 		if (itemHit == OK || itemHit == CANCEL) break;
15574 		if (itemHit == DICO_DRAWLEADS || itemHit == DICO_DRAWBODY ||
15575 			itemHit == DICO_REVEXPORTORD)
15576 		{
15577 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
15578 			continue;
15579 		}
15580 	}
15581 	if (itemHit == OK)
15582 	{
15583 		style = 0;
15584 		index = DiaGetPopupEntry(dia, DICO_INPUTLOC);
15585 		style |= index << ICONSTYLESIDEINSH;
15586 		index = DiaGetPopupEntry(dia, DICO_OUTPUTLOC);
15587 		style |= index << ICONSTYLESIDEOUTSH;
15588 		index = DiaGetPopupEntry(dia, DICO_BIDIRLOC);
15589 		style |= index << ICONSTYLESIDEBIDIRSH;
15590 		index = DiaGetPopupEntry(dia, DICO_POWERLOC);
15591 		style |= index << ICONSTYLESIDEPOWERSH;
15592 		index = DiaGetPopupEntry(dia, DICO_GROUNDLOC);
15593 		style |= index << ICONSTYLESIDEGROUNDSH;
15594 		index = DiaGetPopupEntry(dia, DICO_CLOCKLOC);
15595 		style |= index << ICONSTYLESIDECLOCKSH;
15596 		index = DiaGetPopupEntry(dia, DICO_EXPORTTECH);
15597 		style |= index << ICONSTYLETECHSH;
15598 
15599 		index = DiaGetPopupEntry(dia, DICO_PORTLOC);
15600 		style |= index << ICONSTYLEPORTLOCSH;
15601 		index = DiaGetPopupEntry(dia, DICO_PORTSTYLE);
15602 		style |= index << ICONSTYLEPORTSTYLESH;
15603 		index = DiaGetPopupEntry(dia, DICO_INSTANCELOC);
15604 		style |= index << ICONINSTLOCSH;
15605 
15606 		if (DiaGetControl(dia, DICO_DRAWLEADS) == 0) style |= ICONSTYLEDRAWNOLEADS;
15607 		if (DiaGetControl(dia, DICO_DRAWBODY) == 0) style |= ICONSTYLEDRAWNOBODY;
15608 		if (DiaGetControl(dia, DICO_REVEXPORTORD) != 0) style |= ICONSTYLEREVEXPORT;
15609 		if (style != origstyle)
15610 			setval((INTBIG)us_tool, VTOOL, x_("USER_icon_style"), style, VINTEGER);
15611 
15612 		i = myatoi(DiaGetText(dia, DICO_LEADLENGTH));
15613 		if (i != leadlength)
15614 			setval((INTBIG)us_tool, VTOOL, x_("USER_icon_lead_length"), i, VINTEGER);
15615 		i = myatoi(DiaGetText(dia, DICO_LEADSPACING));
15616 		if (i != leadspacing)
15617 			setval((INTBIG)us_tool, VTOOL, x_("USER_icon_lead_spacing"), i, VINTEGER);
15618 	}
15619 	DiaDoneDialog(dia);
15620 	return(0);
15621 }
15622 
15623 /****************************** LANGUAGE INTERPRETER DIALOG ******************************/
15624 
15625 /* Language: Java options */
15626 static DIALOGITEM us_javaoptdialogitems[] =
15627 {
15628  /*  1 */ {0, {88,112,112,192}, BUTTON, N_("OK")},
15629  /*  2 */ {0, {88,16,112,96}, BUTTON, N_("Cancel")},
15630  /*  3 */ {0, {8,8,24,172}, CHECK, N_("Disable compiler")},
15631  /*  4 */ {0, {32,8,48,172}, CHECK, N_("Disable evaluation")},
15632  /*  5 */ {0, {56,8,72,172}, CHECK, N_("Enable Jose")}
15633 };
15634 static DIALOG us_javaoptdialog = {{75,75,196,277}, N_("Java Options"), 0, 5, us_javaoptdialogitems, 0, 0};
15635 
15636 /* special items for the "Java options" command: */
15637 #define DLJO_DISCOMPILER    3		/* Disable compiler (check) */
15638 #define DLJO_DISEVALUATE    4		/* Disable evaluation (check) */
15639 #define DLJO_USEJOSE        5		/* Use Jose (check) */
15640 
us_javaoptionsdlog(void)15641 INTBIG us_javaoptionsdlog(void)
15642 {
15643 	REGISTER INTBIG itemHit, newflags;
15644 	REGISTER void *dia;
15645 
15646 	/* display the java options dialog box */
15647 	dia = DiaInitDialog(&us_javaoptdialog);
15648 	if (dia == 0) return(0);
15649 	if ((us_javaflags&JAVANOCOMPILER) != 0) DiaSetControl(dia, DLJO_DISCOMPILER, 1);
15650 	if ((us_javaflags&JAVANOEVALUATE) != 0) DiaSetControl(dia, DLJO_DISEVALUATE, 1);
15651 	if ((us_javaflags&JAVAUSEJOSE) != 0) DiaSetControl(dia, DLJO_USEJOSE, 1);
15652 #ifndef DBMIRRORTOOL
15653 	DiaDimItem(DLJO_USEJOSE);
15654 #endif
15655 
15656 	/* loop until done */
15657 	for(;;)
15658 	{
15659 		itemHit = DiaNextHit(dia);
15660 		if (itemHit == OK || itemHit == CANCEL) break;
15661 		if (itemHit == DLJO_DISCOMPILER || itemHit == DLJO_DISEVALUATE || itemHit == DLJO_USEJOSE)
15662 		{
15663 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
15664 			continue;
15665 		}
15666 	}
15667 	if (itemHit != CANCEL)
15668 	{
15669 		newflags = 0;
15670 		if (DiaGetControl(dia, DLJO_DISCOMPILER) != 0) newflags |= JAVANOCOMPILER;
15671 		if (DiaGetControl(dia, DLJO_DISEVALUATE) != 0) newflags |= JAVANOEVALUATE;
15672 		if (DiaGetControl(dia, DLJO_USEJOSE) != 0) newflags |= JAVAUSEJOSE;
15673 		if (newflags != us_javaflags)
15674 			setvalkey((INTBIG)us_tool, VTOOL, us_java_flags_key, newflags, VINTEGER);
15675 	}
15676 	DiaDoneDialog(dia);
15677 	return(0);
15678 }
15679 
15680 /****************************** LAYER HIGHLIGHT DIALOG ******************************/
15681 
15682 /* Layer Highlighting */
15683 static DIALOGITEM us_highlightlayerdialogitems[] =
15684 {
15685  /*  1 */ {0, {108,184,132,248}, BUTTON, N_("Done")},
15686  /*  2 */ {0, {12,184,36,248}, BUTTON, N_("None")},
15687  /*  3 */ {0, {8,8,136,170}, SCROLL, x_("")}
15688 };
15689 static DIALOG us_highlightlayerdialog = {{50,75,195,334}, N_("Layer to Highlight"), 0, 3, us_highlightlayerdialogitems, 0, 0};
15690 
15691 /* special items for the "highlight layer" command: */
15692 #define DHGL_NOLAYER    2		/* No layer (button) */
15693 #define DHGL_LAYERLIST  3		/* Layer list (scroll) */
15694 
us_highlayerlog(void)15695 INTBIG us_highlayerlog(void)
15696 {
15697 	REGISTER INTBIG itemHit, i;
15698 	REGISTER INTBIG funct;
15699 	REGISTER CHAR *la;
15700 	CHAR buf[2], *newpar[3];
15701 	REGISTER void *dia;
15702 
15703 	if (us_needwindow()) return(0);
15704 
15705 	/* display the grid settings dialog box */
15706 	dia = DiaInitDialog(&us_highlightlayerdialog);
15707 	if (dia == 0) return(0);
15708 	DiaInitTextDialog(dia, DHGL_LAYERLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
15709 		SCREPORT|SCSELMOUSE);
15710 	for(i=0; i<el_curtech->layercount; i++)
15711 	{
15712 		if (el_curtech->layers[i]->bits == LAYERO ||
15713 			el_curtech->layers[i]->bits == LAYERN) continue;
15714 		funct = layerfunction(el_curtech, i);
15715 		if ((funct&LFPSEUDO) != 0) continue;
15716 		DiaStuffLine(dia, DHGL_LAYERLIST, layername(el_curtech, i));
15717 	}
15718 	DiaSelectLine(dia, DHGL_LAYERLIST, -1);
15719 
15720 	/* loop until done */
15721 	for(;;)
15722 	{
15723 		itemHit = DiaNextHit(dia);
15724 		if (itemHit == OK) break;
15725 		if (itemHit == DHGL_NOLAYER)
15726 		{
15727 			DiaSelectLine(dia, DHGL_LAYERLIST, -1);
15728 			newpar[0] = x_("default");
15729 			us_color(1, newpar);
15730 			continue;
15731 		}
15732 		if (itemHit == DHGL_LAYERLIST)
15733 		{
15734 			i = DiaGetCurLine(dia, DHGL_LAYERLIST);
15735 			if (i < 0) continue;
15736 			la = DiaGetScrollLine(dia, DHGL_LAYERLIST, i);
15737 			for(i=0; i<el_curtech->layercount; i++)
15738 				if (estrcmp(la, layername(el_curtech, i)) == 0) break;
15739 			if (i >= el_curtech->layercount) continue;
15740 			newpar[0] = x_("default");
15741 			us_color(1, newpar);
15742 			la = us_layerletters(el_curtech, i);
15743 			buf[0] = *la;
15744 			buf[1] = 0;
15745 			newpar[0] = x_("highlight");
15746 			newpar[1] = buf;
15747 			us_color(2, newpar);
15748 			continue;
15749 		}
15750 	}
15751 	DiaDoneDialog(dia);
15752 	return(0);
15753 }
15754 
15755 /****************************** LIBRARY PATH DIALOG ******************************/
15756 
15757 /* Library paths */
15758 static DIALOGITEM us_librarypathdialogitems[] =
15759 {
15760  /*  1 */ {0, {76,312,100,376}, BUTTON, N_("OK")},
15761  /*  2 */ {0, {76,32,100,96}, BUTTON, N_("Cancel")},
15762  /*  3 */ {0, {8,16,24,220}, MESSAGE, N_("Location of library files:")},
15763  /*  4 */ {0, {32,8,64,400}, EDITTEXT, x_("")}
15764 };
15765 static DIALOG us_librarypathdialog = {{50,75,159,485}, N_("Current Library Path"), 0, 4, us_librarypathdialogitems, 0, 0};
15766 
15767 /* special items for the "library paths" dialog: */
15768 #define DLBP_LIBLOC     4		/* library file location (stat text) */
15769 
us_librarypathdlog(void)15770 INTBIG us_librarypathdlog(void)
15771 {
15772 	INTBIG itemHit;
15773 	CHAR *pt;
15774 	REGISTER void *dia;
15775 
15776 	/* display the library paths dialog box */
15777 	dia = DiaInitDialog(&us_librarypathdialog);
15778 	if (dia == 0) return(0);
15779 	DiaSetText(dia, DLBP_LIBLOC, el_libdir);
15780 
15781 	/* loop until done */
15782 	for(;;)
15783 	{
15784 		itemHit = DiaNextHit(dia);
15785 		if (itemHit == CANCEL) break;
15786 		if (itemHit == OK && DiaValidEntry(dia, DLBP_LIBLOC)) break;
15787 	}
15788 
15789 	if (itemHit != CANCEL)
15790 	{
15791 		pt = DiaGetText(dia, DLBP_LIBLOC);
15792 		if (estrcmp(pt, el_libdir) != 0) setlibdir(pt);
15793 	}
15794 	DiaDoneDialog(dia);
15795 	return(0);
15796 }
15797 
15798 /****************************** LIBRARY SELECTION DIALOG ******************************/
15799 
15800 /* Change Library */
15801 static DIALOGITEM us_chglibrarydialogitems[] =
15802 {
15803  /*  1 */ {0, {164,220,188,300}, BUTTON, N_("OK")},
15804  /*  2 */ {0, {116,220,140,300}, BUTTON, N_("Cancel")},
15805  /*  3 */ {0, {4,4,20,128}, MESSAGE, N_("Current Library:")},
15806  /*  4 */ {0, {4,132,20,316}, MESSAGE, x_("")},
15807  /*  5 */ {0, {52,4,196,196}, SCROLL, x_("")},
15808  /*  6 */ {0, {32,16,48,168}, MESSAGE|INACTIVE, N_("Switch to Library:")}
15809 };
15810 static DIALOG us_chglibrarydialog = {{75,75,280,401}, N_("Set Current Library"), 0, 6, us_chglibrarydialogitems, 0, 0};
15811 
15812 /* special items for the "change current library" dialog: */
15813 #define DCHL_CURLIB    4		/* current library (stat text) */
15814 #define DCHL_LIBLIST   5		/* library list (scroll) */
15815 
us_oldlibrarydlog(void)15816 INTBIG us_oldlibrarydlog(void)
15817 {
15818 	REGISTER INTBIG itemHit, i, listlen;
15819 	REGISTER LIBRARY *lib;
15820 	REGISTER CHAR *pt;
15821 	REGISTER void *dia;
15822 
15823 	/* display the library selection dialog box */
15824 	dia = DiaInitDialog(&us_chglibrarydialog);
15825 	if (dia == 0) return(0);
15826 	DiaSetText(dia, DCHL_CURLIB, el_curlib->libname);
15827 	DiaInitTextDialog(dia, DCHL_LIBLIST, topoflibs, nextlibs, DiaNullDlogDone, 0,
15828 		SCSELMOUSE|SCDOUBLEQUIT);
15829 
15830 	/* select the current library */
15831 	listlen = DiaGetNumScrollLines(dia, DCHL_LIBLIST);
15832 	for(i=0; i<listlen; i++)
15833 	{
15834 		pt = DiaGetScrollLine(dia, DCHL_LIBLIST, i);
15835 		if (namesame(pt, el_curlib->libname) == 0)
15836 		{
15837 			DiaSelectLine(dia, DCHL_LIBLIST, i);
15838 			break;
15839 		}
15840 	}
15841 
15842 	/* loop until done */
15843 	for(;;)
15844 	{
15845 		itemHit = DiaNextHit(dia);
15846 		if (itemHit == OK || itemHit == CANCEL) break;
15847 	}
15848 
15849 	lib = el_curlib;
15850 	if (itemHit != CANCEL)
15851 	{
15852 		pt = DiaGetScrollLine(dia, DCHL_LIBLIST, DiaGetCurLine(dia, DCHL_LIBLIST));
15853 		lib = getlibrary(pt);
15854 	}
15855 	DiaDoneDialog(dia);
15856 	if (lib != NOLIBRARY && lib != el_curlib)
15857 		us_switchtolibrary(lib);
15858 	return(0);
15859 }
15860 
15861 /****************************** NODE: CREATE ANNULAR RING DIALOG ******************************/
15862 
15863 /* Annular Ring */
15864 static DIALOGITEM us_annringdialogitems[] =
15865 {
15866  /*  1 */ {0, {268,176,292,240}, BUTTON, N_("OK")},
15867  /*  2 */ {0, {268,20,292,84}, BUTTON, N_("Cancel")},
15868  /*  3 */ {0, {164,12,180,160}, MESSAGE, N_("Inner Radius:")},
15869  /*  4 */ {0, {164,164,180,244}, EDITTEXT, x_("")},
15870  /*  5 */ {0, {188,12,204,160}, MESSAGE, N_("Outer Radius:")},
15871  /*  6 */ {0, {188,164,204,244}, EDITTEXT, x_("")},
15872  /*  7 */ {0, {212,12,228,160}, MESSAGE, N_("Number of segments:")},
15873  /*  8 */ {0, {212,164,228,244}, EDITTEXT, x_("32")},
15874  /*  9 */ {0, {236,12,252,160}, MESSAGE, N_("Number of degrees:")},
15875  /* 10 */ {0, {236,164,252,244}, EDITTEXT, x_("360")},
15876  /* 11 */ {0, {8,8,24,172}, MESSAGE, N_("Layer to use for ring:")},
15877  /* 12 */ {0, {28,8,156,244}, SCROLL, x_("")}
15878 };
15879 static DIALOG us_annringdialog = {{75,75,376,330}, N_("Annulus Construction"), 0, 12, us_annringdialogitems, 0, 0};
15880 
15881 /* special items for the "Annular ring" dialog: */
15882 #define DANR_INNERRADIUS  4		/* inner radius (edit text) */
15883 #define DANR_OUTERRADIUS  6		/* outer radius (edit text) */
15884 #define DANR_NUMSEGS      8		/* number of segments (edit text) */
15885 #define DANR_NUMDEGREES  10		/* number of degrees (edit text) */
15886 #define DANR_LAYER       12		/* layer to use (scroll) */
15887 
us_annularringdlog(void)15888 INTBIG us_annularringdlog(void)
15889 {
15890 	INTBIG itemHit, i;
15891 	REGISTER INTBIG lx, hx, ly, hy, cx, cy, layers, fun;
15892 	REGISTER NODEINST *ni;
15893 	REGISTER NODEPROTO *layer, *parent, *prim;
15894 	CHAR inner[20], outer[20], segs[20], degrees[20], *pars[6];
15895 	static POLYGON *poly = NOPOLYGON;
15896 	HIGHLIGHT newhigh;
15897 	REGISTER void *dia;
15898 
15899 	parent = us_needcell();
15900 	if (parent == NONODEPROTO) return(0);
15901 
15902 	/* get polygon */
15903 	(void)needstaticpolygon(&poly, 4, us_tool->cluster);
15904 
15905 	/* count all pure-layer nodes in the current technology */
15906 	layers = 0;
15907 	for(prim = el_curtech->firstnodeproto; prim != NONODEPROTO; prim = prim->nextnodeproto)
15908 	{
15909 		fun = (prim->userbits&NFUNCTION) >> NFUNCTIONSH;
15910 		if (fun == NPNODE) layers++;
15911 	}
15912 	if (layers <= 0)
15913 	{
15914 		us_abortcommand(_("This technology has no pure-layer nodes"));
15915 		return(0);
15916 	}
15917 
15918 	/* display the window view dialog box */
15919 	dia = DiaInitDialog(&us_annringdialog);
15920 	if (dia == 0) return(0);
15921 	DiaInitTextDialog(dia, DANR_LAYER, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
15922 		SCSELMOUSE);
15923 	for(prim = el_curtech->firstnodeproto; prim != NONODEPROTO; prim = prim->nextnodeproto)
15924 	{
15925 		fun = (prim->userbits&NFUNCTION) >> NFUNCTIONSH;
15926 		if (fun != NPNODE) continue;
15927 		DiaStuffLine(dia, DANR_LAYER, prim->protoname);
15928 	}
15929 	DiaSelectLine(dia, DANR_LAYER, 0);
15930 	DiaSetText(dia, DANR_NUMSEGS, x_("32"));
15931 	DiaSetText(dia, DANR_NUMDEGREES, x_("360"));
15932 
15933 	/* loop until done */
15934 	for(;;)
15935 	{
15936 		itemHit = DiaNextHit(dia);
15937 		if (itemHit == OK || itemHit == CANCEL) break;
15938 	}
15939 
15940 	if (itemHit == OK)
15941 	{
15942 		/* figure out which pure-layer node to create */
15943 		i = DiaGetCurLine(dia, DANR_LAYER);
15944 		layer = getnodeproto(DiaGetScrollLine(dia, DANR_LAYER, i));
15945 		if (layer == NONODEPROTO) { DiaDoneDialog(dia);   return(0); }
15946 
15947 		/* create the pure-layer node */
15948 		cx = (el_curwindowpart->screenlx + el_curwindowpart->screenhx) / 2;
15949 		cy = (el_curwindowpart->screenly + el_curwindowpart->screenhy) / 2;
15950 		lx = cx - (layer->highx - layer->lowx) / 2;
15951 		hx = lx + layer->highx - layer->lowx;
15952 		ly = cy - (layer->highy - layer->lowy) / 2;
15953 		hy = ly + layer->highy - layer->lowy;
15954 		ni = newnodeinst(layer, lx, hx, ly, hy, 0, 0, parent);
15955 		if (ni == NONODEINST) { DiaDoneDialog(dia);   return(0); }
15956 		endobjectchange((INTBIG)ni, VNODEINST);
15957 
15958 		/* highlight the pure-layer node */
15959 		us_clearhighlightcount();
15960 		newhigh.status = HIGHFROM;
15961 		newhigh.cell = parent;
15962 		newhigh.fromgeom = ni->geom;
15963 		newhigh.fromport = NOPORTPROTO;
15964 		newhigh.frompoint = 0;
15965 		us_addhighlight(&newhigh);
15966 
15967 		/* turn it into an annular ring */
15968 		estrcpy(inner, DiaGetText(dia, DANR_INNERRADIUS));
15969 		estrcpy(outer, DiaGetText(dia, DANR_OUTERRADIUS));
15970 		estrcpy(segs, DiaGetText(dia, DANR_NUMSEGS));
15971 		estrcpy(degrees, DiaGetText(dia, DANR_NUMDEGREES));
15972 		pars[0] = x_("trace");
15973 		pars[1] = x_("construct-annulus");
15974 		pars[2] = inner;
15975 		pars[3] = outer;
15976 		pars[4] = segs;
15977 		pars[5] = degrees;
15978 		us_node(6, pars);
15979 	}
15980 	DiaDoneDialog(dia);
15981 	return(0);
15982 }
15983 
15984 /****************************** NODE: CREATE LAYOUT TEXT DIALOG ******************************/
15985 
15986 /* Node: Make Text Layout */
15987 static DIALOGITEM us_spelldialogitems[] =
15988 {
15989  /*  1 */ {0, {196,192,220,272}, BUTTON, N_("OK")},
15990  /*  2 */ {0, {196,12,220,92}, BUTTON, N_("Cancel")},
15991  /*  3 */ {0, {8,200,24,248}, EDITTEXT, x_("")},
15992  /*  4 */ {0, {8,8,24,196}, MESSAGE, N_("Size (max 63):")},
15993  /*  5 */ {0, {164,8,180,72}, MESSAGE, N_("Message:")},
15994  /*  6 */ {0, {164,76,180,272}, EDITTEXT, x_("")},
15995  /*  7 */ {0, {136,76,152,272}, POPUP, x_("")},
15996  /*  8 */ {0, {136,8,152,72}, MESSAGE, N_("Layer:")},
15997  /*  9 */ {0, {88,76,104,268}, POPUP, x_("")},
15998  /* 10 */ {0, {88,8,104,72}, MESSAGE, N_("Font:")},
15999  /* 11 */ {0, {112,8,128,92}, CHECK, N_("Italic")},
16000  /* 12 */ {0, {112,100,128,168}, CHECK, N_("Bold")},
16001  /* 13 */ {0, {112,176,128,272}, CHECK, N_("Underline")},
16002  /* 14 */ {0, {36,200,52,248}, EDITTEXT, x_("")},
16003  /* 15 */ {0, {36,8,52,196}, MESSAGE, N_("Scale factor:")},
16004  /* 16 */ {0, {64,200,80,248}, EDITTEXT, x_("")},
16005  /* 17 */ {0, {64,8,80,196}, MESSAGE, N_("Dot separation (lambda):")}
16006 };
16007 static DIALOG us_spelldialog = {{75,75,304,356}, N_("Create Text Layout"), 0, 17, us_spelldialogitems, 0, 0};
16008 
16009 /* special items for the "Layout Text" dialog: */
16010 #define DPLT_TEXTSIZE     3		/* Text size (edit text) */
16011 #define DPLT_TEXT         6		/* Text to place (edit text) */
16012 #define DPLT_LAYER        7		/* Layer (popup) */
16013 #define DPLT_FONT         9		/* Font (popup) */
16014 #define DPLT_FONT_L      10		/* Font label (stat text) */
16015 #define DPLT_ITALIC      11		/* Italic (check) */
16016 #define DPLT_BOLD        12		/* Bold (check) */
16017 #define DPLT_UNDERLINE   13		/* Underline (check) */
16018 #define DPLT_SCALE       14		/* Scale (edit text) */
16019 #define DPLT_SEPARATION  16		/* Dot separation (edit text) */
16020 
us_placetextdlog(void)16021 INTBIG us_placetextdlog(void)
16022 {
16023 	INTBIG itemHit, layers, fun;
16024 	CHAR **layernames, line[20];
16025 	static INTBIG lastprim = 0, lastsize = 12, lastfont = 0, lastscale = 1,
16026 		lastitalic = 0, lastbold = 0, lastseparation = 0, lastunderline = 0;
16027 	REGISTER NODEPROTO *prim;
16028 	REGISTER void *dia;
16029 
16030 	/* count all pure-layer nodes in the current technology */
16031 	layers = 0;
16032 	for(prim = el_curtech->firstnodeproto; prim != NONODEPROTO; prim = prim->nextnodeproto)
16033 	{
16034 		fun = (prim->userbits&NFUNCTION) >> NFUNCTIONSH;
16035 		if (fun == NPNODE) layers++;
16036 	}
16037 	if (layers <= 0)
16038 	{
16039 		us_abortcommand(_("This technology has no pure-layer nodes"));
16040 		return(0);
16041 	}
16042 
16043 	/* display the text-layout dialog box */
16044 	dia = DiaInitDialog(&us_spelldialog);
16045 	if (dia == 0) return(0);
16046 	esnprintf(line, 20, x_("%ld"), lastsize);
16047 	DiaSetText(dia, DPLT_TEXTSIZE, line);
16048 	esnprintf(line, 20, x_("%ld"), lastscale);
16049 	DiaSetText(dia, DPLT_SCALE, line);
16050 	esnprintf(line, 20, x_("%ld"), lastseparation);
16051 	DiaSetText(dia, DPLT_SEPARATION, line);
16052 	layernames = (CHAR **)emalloc(layers * (sizeof (CHAR *)), el_tempcluster);
16053 	if (layernames == 0) return(0);
16054 	layers = 0;
16055 	for(prim = el_curtech->firstnodeproto; prim != NONODEPROTO; prim = prim->nextnodeproto)
16056 	{
16057 		fun = (prim->userbits&NFUNCTION) >> NFUNCTIONSH;
16058 		if (fun != NPNODE) continue;
16059 		layernames[layers++] = prim->protoname;
16060 	}
16061 	DiaSetPopup(dia, DPLT_LAYER, layers, layernames);
16062 	if (lastprim < layers) DiaSetPopupEntry(dia, DPLT_LAYER, lastprim);
16063 	if (us_lastplacetextmessage != 0)
16064 		DiaSetText(dia, -DPLT_TEXT, us_lastplacetextmessage);
16065 	if (graphicshas(CANCHOOSEFACES))
16066 	{
16067 		DiaUnDimItem(dia, DPLT_FONT_L);
16068 		us_setpopupface(DPLT_FONT, lastfont, TRUE, dia);
16069 	} else
16070 	{
16071 		DiaDimItem(dia, DPLT_FONT_L);
16072 	}
16073 	if (graphicshas(CANMODIFYFONTS))
16074 	{
16075 		DiaUnDimItem(dia, DPLT_ITALIC);
16076 		DiaUnDimItem(dia, DPLT_BOLD);
16077 		DiaUnDimItem(dia, DPLT_UNDERLINE);
16078 		DiaSetControl(dia, DPLT_ITALIC, lastitalic);
16079 		DiaSetControl(dia, DPLT_BOLD, lastbold);
16080 		DiaSetControl(dia, DPLT_UNDERLINE, lastunderline);
16081 	} else
16082 	{
16083 		DiaDimItem(dia, DPLT_ITALIC);
16084 		DiaDimItem(dia, DPLT_BOLD);
16085 		DiaDimItem(dia, DPLT_UNDERLINE);
16086 	}
16087 
16088 	/* loop until done */
16089 	for(;;)
16090 	{
16091 		itemHit = DiaNextHit(dia);
16092 		if (itemHit == OK || itemHit == CANCEL) break;
16093 		if (itemHit == DPLT_ITALIC || itemHit == DPLT_BOLD || itemHit == DPLT_UNDERLINE)
16094 		{
16095 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
16096 			continue;
16097 		}
16098 	}
16099 	lastsize = eatoi(DiaGetText(dia, DPLT_TEXTSIZE));
16100 	lastscale = eatoi(DiaGetText(dia, DPLT_SCALE));
16101 	lastseparation = eatoi(DiaGetText(dia, DPLT_SEPARATION));
16102 
16103 	if (graphicshas(CANCHOOSEFACES))
16104 	{
16105 		lastfont = us_getpopupface(DPLT_FONT, dia);
16106 	}
16107 	if (graphicshas(CANMODIFYFONTS))
16108 	{
16109 		lastitalic = DiaGetControl(dia, DPLT_ITALIC);
16110 		lastbold = DiaGetControl(dia, DPLT_BOLD);
16111 		lastunderline = DiaGetControl(dia, DPLT_UNDERLINE);
16112 	}
16113 	lastprim = DiaGetPopupEntry(dia, DPLT_LAYER);
16114 	if (us_lastplacetextmessage != 0) efree((CHAR *)us_lastplacetextmessage);
16115 	(void)allocstring(&us_lastplacetextmessage, DiaGetText(dia, DPLT_TEXT), us_tool->cluster);
16116 
16117 	if (itemHit == OK)
16118 	{
16119 		us_layouttext(layernames[lastprim], lastsize, lastscale, lastfont, lastitalic,
16120 			lastbold, lastunderline, lastseparation, us_lastplacetextmessage);
16121 	}
16122 	DiaDoneDialog(dia);
16123 	efree((CHAR *)layernames);
16124 	return(0);
16125 }
16126 
16127 /****************************** NODE CREATION OPTIONS DIALOG ******************************/
16128 
16129 /* New Node Options */
16130 static DIALOGITEM us_defnodedialogitems[] =
16131 {
16132  /*  1 */ {0, {384,352,408,416}, BUTTON, N_("OK")},
16133  /*  2 */ {0, {344,352,368,416}, BUTTON, N_("Cancel")},
16134  /*  3 */ {0, {32,208,48,318}, EDITTEXT, x_("")},
16135  /*  4 */ {0, {32,24,48,205}, MESSAGE, N_("X size of new primitives:")},
16136  /*  5 */ {0, {56,24,72,205}, MESSAGE, N_("Y size of new primitives:")},
16137  /*  6 */ {0, {56,208,72,318}, EDITTEXT, x_("")},
16138  /*  7 */ {0, {8,4,24,142}, MESSAGE, N_("For primitive:")},
16139  /*  8 */ {0, {8,144,24,354}, POPUP, x_("")},
16140  /*  9 */ {0, {164,24,180,230}, MESSAGE, N_("Rotation of new nodes:")},
16141  /* 10 */ {0, {164,240,180,293}, EDITTEXT, x_("")},
16142  /* 11 */ {0, {164,300,180,405}, CHECK, N_("Transposed")},
16143  /* 12 */ {0, {132,4,133,422}, DIVIDELINE, x_("")},
16144  /* 13 */ {0, {140,4,156,152}, MESSAGE, N_("For all nodes:")},
16145  /* 14 */ {0, {188,24,204,338}, CHECK, N_("Disallow modification of locked primitives")},
16146  /* 15 */ {0, {212,24,228,338}, CHECK, N_("Move after Duplicate")},
16147  /* 16 */ {0, {236,24,252,338}, CHECK, N_("Duplicate/Array/Extract copies exports")},
16148  /* 17 */ {0, {108,40,124,246}, MESSAGE, N_("Rotation of new nodes:")},
16149  /* 18 */ {0, {108,256,124,309}, EDITTEXT, x_("")},
16150  /* 19 */ {0, {108,317,124,422}, CHECK, N_("Transposed")},
16151  /* 20 */ {0, {84,24,100,249}, CHECK, N_("Override default orientation")},
16152  /* 21 */ {0, {292,268,308,309}, EDITTEXT, x_("")},
16153  /* 22 */ {0, {337,20,453,309}, SCROLL, x_("")},
16154  /* 23 */ {0, {316,20,332,309}, MESSAGE, N_("Primitive function abbreviations:")},
16155  /* 24 */ {0, {460,20,476,165}, MESSAGE, N_("Function:")},
16156  /* 25 */ {0, {460,168,476,309}, EDITTEXT, x_("")},
16157  /* 26 */ {0, {260,4,261,422}, DIVIDELINE, x_("")},
16158  /* 27 */ {0, {268,4,284,185}, MESSAGE, N_("Node naming:")},
16159  /* 28 */ {0, {292,20,308,265}, MESSAGE, N_("Length of cell abbreviations:")},
16160  /* 29 */ {0, {261,332,476,333}, DIVIDELINE, x_("")}
16161 };
16162 static DIALOG us_defnodedialog = {{50,75,535,507}, N_("New Node Options"), 0, 29, us_defnodedialogitems, 0, 0};
16163 
16164 /* special items for the "new node defaults" dialog: */
16165 #define DDFN_XSIZE            3		/* X size (edit text) */
16166 #define DDFN_YSIZE            6		/* Y size (edit text) */
16167 #define DDFN_PRIMNAME         8		/* Primitive name (popup) */
16168 #define DDFN_ALLROTATION     10		/* all Rotation (edit text) */
16169 #define DDFN_ALLTRANSPOSE    11		/* all Transposed (check) */
16170 #define DDFN_ALLOWPRIMMOD    14		/* Allow prim mod (check) */
16171 #define DDFN_MOVEAFTERDUP    15		/* Move after dup (check) */
16172 #define DDFN_COPYPORTS       16		/* Dup copies ports (check) */
16173 #define DDFN_NODEROTATION_L  17		/* node rotation (stat text) */
16174 #define DDFN_NODEROTATION    18		/* node rotation (edit text) */
16175 #define DDFN_NODETRANSPOSE   19		/* node Transposed (check) */
16176 #define DDFN_OVERRIDEORIENT  20		/* override orientation (check) */
16177 #define DDFN_ABBREVLEN       21		/* Length of abbreviations (edit text) */
16178 #define DDFN_FUNCTLIST       22		/* List of functions (scroll) */
16179 #define DDFN_FUNNAME         24		/* Function name (message) */
16180 #define DDFN_ABBREV          25		/* New abbreviation (edit text) */
16181 
16182 typedef struct
16183 {
16184 	INTBIG xsize, ysize;
16185 	INTBIG pangle;
16186 } DEFPRIMINFO;
16187 
us_defnodedlog(void)16188 INTBIG us_defnodedlog(void)
16189 {
16190 	REGISTER INTBIG itemHit, i, j, pangle, thispangle, numprims, reloadprim, value, len;
16191 	INTBIG plx, ply, phx, phy, lx, pxs, pys, nodesize[2];
16192 	REGISTER NODEPROTO *thisprim, *np;
16193 	REGISTER BOOLEAN abbrevchanged;
16194 	REGISTER VARIABLE *var;
16195 	REGISTER CHAR **primnames;
16196 	REGISTER DEFPRIMINFO *dpi;
16197 	REGISTER INTBIG abbrevlen;
16198 	CHAR **shortnames, *name, *pt, num[20];
16199 	REGISTER void *infstr;
16200 	REGISTER void *dia;
16201 
16202 	/* display the defnode dialog box */
16203 	dia = DiaInitDialog(&us_defnodedialog);
16204 	if (dia == 0) return(0);
16205 
16206 	/* construct lists of primitives */
16207 	numprims = 0;
16208 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16209 		numprims++;
16210 	primnames = (CHAR **)emalloc(numprims * (sizeof (CHAR *)), el_tempcluster);
16211 	numprims = 0;
16212 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16213 		primnames[numprims++] = np->protoname;
16214 	DiaSetPopup(dia, DDFN_PRIMNAME, numprims, primnames);
16215 	efree((CHAR *)primnames);
16216 
16217 	/* save existing state */
16218 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16219 	{
16220 		dpi = (DEFPRIMINFO *)emalloc(sizeof (DEFPRIMINFO), el_tempcluster);
16221 		if (dpi == 0) return(0);
16222 		np->temp1 = (INTBIG)dpi;
16223 		defaultnodesize(np, &pxs, &pys);
16224 		nodeprotosizeoffset(np, &plx, &ply, &phx, &phy, NONODEPROTO);
16225 		dpi->xsize = pxs - plx - phx;
16226 		dpi->ysize = pys - ply - phy;
16227 		var = getvalkey((INTBIG)np, VNODEPROTO, VINTEGER, us_placement_angle_key);
16228 		if (var == NOVARIABLE) dpi->pangle = -1; else
16229 			dpi->pangle = var->addr;
16230 	}
16231 
16232 	/* load defaults for primitives */
16233 	thisprim = el_curtech->firstnodeproto;
16234 
16235 	/* load defaults for all nodes */
16236 	var = getvalkey((INTBIG)us_tool, VTOOL, VINTEGER, us_placement_angle_key);
16237 	if (var == NOVARIABLE) pangle = 0; else pangle = var->addr;
16238 	DiaSetText(dia, -DDFN_ALLROTATION, frtoa(pangle%3600*WHOLE/10));
16239 	DiaSetControl(dia, DDFN_ALLTRANSPOSE, (pangle >= 3600 ? 1 : 0));
16240 	DiaSetControl(dia, DDFN_ALLOWPRIMMOD, (us_useroptions&NOPRIMCHANGES) != 0 ? 1 : 0);
16241 	DiaSetControl(dia, DDFN_MOVEAFTERDUP, (us_useroptions&NOMOVEAFTERDUP) == 0 ? 1 : 0);
16242 	DiaSetControl(dia, DDFN_COPYPORTS, (us_useroptions&DUPCOPIESPORTS) != 0 ? 1 : 0);
16243 
16244 	/* load node abbreviation information */
16245 	var = getvalkey((INTBIG)net_tool, VTOOL, VINTEGER, net_node_abbrevlen_key);
16246 	if (var == NOVARIABLE) abbrevlen = NETDEFAULTABBREVLEN; else
16247 		abbrevlen = var->addr;
16248 	esnprintf(num, 20, x_("%ld"), abbrevlen);
16249 	DiaSetText(dia, DDFN_ABBREVLEN, num);
16250 	var = getvalkey((INTBIG)net_tool, VTOOL, VSTRING|VISARRAY, net_node_abbrev_key);
16251 	if (var == NOVARIABLE) len = 0; else
16252 		len = getlength(var);
16253 	shortnames = (CHAR **)emalloc(MAXNODEFUNCTION * (sizeof (CHAR *)), net_tool->cluster);
16254 	if (shortnames == 0) return(0);
16255 	for(i=0; i<MAXNODEFUNCTION; i++)
16256 	{
16257 		name = nodefunctionshortname(i);
16258 		if (i < len)
16259 		{
16260 			pt = ((CHAR **)var->addr)[i];
16261 			if (*pt != 0) name = pt;
16262 		}
16263 		(void)allocstring(&shortnames[i], name, net_tool->cluster);
16264 	}
16265 	DiaInitTextDialog(dia, DDFN_FUNCTLIST, DiaNullDlogList, DiaNullDlogItem,
16266 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
16267 	for(i=0; i<MAXNODEFUNCTION; i++)
16268 	{
16269 		infstr = initinfstr();
16270 		formatinfstr(infstr, x_("%s (%s)"), nodefunctionname(i, NONODEINST), shortnames[i]);
16271 		DiaStuffLine(dia, DDFN_FUNCTLIST, returninfstr(infstr));
16272 	}
16273 	DiaSelectLine(dia, DDFN_FUNCTLIST, 0);
16274 	DiaSetText(dia, DDFN_FUNNAME, nodefunctionname(0, NONODEINST));
16275 	DiaSetText(dia, DDFN_ABBREV, shortnames[0]);
16276 
16277 	/* loop until done */
16278 	reloadprim = 1;
16279 	abbrevchanged = FALSE;
16280 	for(;;)
16281 	{
16282 		if (reloadprim != 0)
16283 		{
16284 			reloadprim = 0;
16285 			dpi = (DEFPRIMINFO *)thisprim->temp1;
16286 			DiaSetPopupEntry(dia, DDFN_PRIMNAME, thisprim->primindex-1);
16287 			DiaSetText(dia, DDFN_XSIZE, latoa(dpi->xsize, 0));
16288 			DiaSetText(dia, DDFN_YSIZE, latoa(dpi->ysize, 0));
16289 			if (dpi->pangle < 0)
16290 			{
16291 				DiaSetControl(dia, DDFN_OVERRIDEORIENT, 0);
16292 				DiaSetText(dia, DDFN_NODEROTATION, x_(""));
16293 				DiaSetControl(dia, DDFN_NODETRANSPOSE, 0);
16294 				DiaDimItem(dia, DDFN_NODEROTATION_L);
16295 				DiaDimItem(dia, DDFN_NODEROTATION);
16296 				DiaDimItem(dia, DDFN_NODETRANSPOSE);
16297 			} else
16298 			{
16299 				DiaSetControl(dia, DDFN_OVERRIDEORIENT, 1);
16300 				DiaUnDimItem(dia, DDFN_NODEROTATION_L);
16301 				DiaUnDimItem(dia, DDFN_NODEROTATION);
16302 				DiaUnDimItem(dia, DDFN_NODETRANSPOSE);
16303 				DiaSetText(dia, DDFN_NODEROTATION, frtoa(dpi->pangle%3600*WHOLE/10));
16304 				DiaSetControl(dia, DDFN_NODETRANSPOSE, (dpi->pangle >= 3600 ? 1 : 0));
16305 			}
16306 		}
16307 
16308 		itemHit = DiaNextHit(dia);
16309 		if (itemHit == OK || itemHit == CANCEL) break;
16310 		if (itemHit == DDFN_PRIMNAME)
16311 		{
16312 			i = DiaGetPopupEntry(dia, DDFN_PRIMNAME);
16313 			for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16314 				if (np->primindex == i+1) break;
16315 			thisprim = np;
16316 			reloadprim = 1;
16317 			continue;
16318 		}
16319 		if (itemHit == DDFN_XSIZE || itemHit == DDFN_YSIZE)
16320 		{
16321 			dpi = (DEFPRIMINFO *)thisprim->temp1;
16322 			dpi->xsize = atola(DiaGetText(dia, DDFN_XSIZE), 0);
16323 			dpi->ysize = atola(DiaGetText(dia, DDFN_YSIZE), 0);
16324 			continue;
16325 		}
16326 		if (itemHit == DDFN_NODEROTATION)
16327 		{
16328 			if (DiaGetControl(dia, DDFN_OVERRIDEORIENT) == 0) continue;
16329 			dpi = (DEFPRIMINFO *)thisprim->temp1;
16330 			dpi->pangle = atofr(DiaGetText(dia, DDFN_NODEROTATION)) * 10 / WHOLE;
16331 			if (DiaGetControl(dia, DDFN_NODETRANSPOSE) != 0) dpi->pangle += 3600;
16332 			continue;
16333 		}
16334 		if (itemHit == DDFN_ALLTRANSPOSE || itemHit == DDFN_ALLOWPRIMMOD ||
16335 			itemHit == DDFN_MOVEAFTERDUP || itemHit == DDFN_COPYPORTS ||
16336 			itemHit == DDFN_NODETRANSPOSE || itemHit == DDFN_OVERRIDEORIENT)
16337 		{
16338 			value = 1 - DiaGetControl(dia, itemHit);
16339 			DiaSetControl(dia, itemHit, value);
16340 			if (itemHit == DDFN_OVERRIDEORIENT)
16341 			{
16342 				dpi = (DEFPRIMINFO *)thisprim->temp1;
16343 				if (value != 0) dpi->pangle = 0; else
16344 					dpi->pangle = -1;
16345 				reloadprim = 1;
16346 			}
16347 			if (itemHit == DDFN_NODETRANSPOSE)
16348 			{
16349 				if (DiaGetControl(dia, DDFN_OVERRIDEORIENT) == 0) continue;
16350 				dpi = (DEFPRIMINFO *)thisprim->temp1;
16351 				dpi->pangle = atofr(DiaGetText(dia, DDFN_NODEROTATION)) * 10 / WHOLE;
16352 				if (DiaGetControl(dia, DDFN_NODETRANSPOSE) != 0) dpi->pangle += 3600;
16353 				reloadprim = 1;
16354 			}
16355 			continue;
16356 		}
16357 		if (itemHit == DDFN_FUNCTLIST)
16358 		{
16359 			i = DiaGetCurLine(dia, DDFN_FUNCTLIST);
16360 			DiaSetText(dia, DDFN_FUNNAME, nodefunctionname(i, NONODEINST));
16361 			DiaSetText(dia, DDFN_ABBREV, shortnames[i]);
16362 			continue;
16363 		}
16364 		if (itemHit == DDFN_ABBREV)
16365 		{
16366 			i = DiaGetCurLine(dia, DDFN_FUNCTLIST);
16367 			pt = DiaGetText(dia, DDFN_ABBREV);
16368 			if (namesame(shortnames[i], pt) == 0) continue;
16369 			abbrevchanged = TRUE;
16370 			(void)reallocstring(&shortnames[i], pt, net_tool->cluster);
16371 			infstr = initinfstr();
16372 			formatinfstr(infstr, x_("%s (%s)"), nodefunctionname(i, NONODEINST), shortnames[i]);
16373 			DiaSetScrollLine(dia, DDFN_FUNCTLIST, i, returninfstr(infstr));
16374 			continue;
16375 		}
16376 	}
16377 	if (itemHit != CANCEL)
16378 	{
16379 		/* handle primitive size changes */
16380 		for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16381 		{
16382 			dpi = (DEFPRIMINFO *)np->temp1;
16383 			defaultnodesize(np, &pxs, &pys);
16384 			nodeprotosizeoffset(np, &plx, &ply, &phx, &phy, NONODEPROTO);
16385 			if (dpi->xsize != pxs - plx - phx || dpi->ysize != pys - ply - phy)
16386 			{
16387 				nodesize[0] = dpi->xsize+plx+phx;
16388 				nodesize[1] = dpi->ysize+ply+phy;
16389 				nodesize[0] = nodesize[0] * WHOLE / el_curlib->lambda[np->tech->techindex];
16390 				nodesize[1] = nodesize[1] * WHOLE / el_curlib->lambda[np->tech->techindex];
16391 				(void)setvalkey((INTBIG)np, VNODEPROTO, el_node_size_default_key,
16392 					(INTBIG)nodesize, VINTEGER|VISARRAY|(2<<VLENGTHSH));
16393 			}
16394 			var = getvalkey((INTBIG)np, VNODEPROTO, VINTEGER, us_placement_angle_key);
16395 			if (var == NOVARIABLE) thispangle = -1; else
16396 				thispangle = var->addr;
16397 			if (thispangle != dpi->pangle)
16398 			{
16399 				if (dpi->pangle < 0)
16400 				{
16401 					(void)delvalkey((INTBIG)np, VNODEPROTO, us_placement_angle_key);
16402 				} else
16403 				{
16404 					setvalkey((INTBIG)np, VNODEPROTO, us_placement_angle_key,
16405 						dpi->pangle, VINTEGER);
16406 				}
16407 			}
16408 		}
16409 
16410 		/* handle changes to all nodes */
16411 		lx = us_useroptions;
16412 		i = DiaGetControl(dia, DDFN_ALLOWPRIMMOD);
16413 		if (i != 0) lx |= NOPRIMCHANGES; else lx &= ~NOPRIMCHANGES;
16414 		i = DiaGetControl(dia, DDFN_MOVEAFTERDUP);
16415 		if (i == 0) lx |= NOMOVEAFTERDUP; else lx &= ~NOMOVEAFTERDUP;
16416 		i = DiaGetControl(dia, DDFN_COPYPORTS);
16417 		if (i != 0) lx |= DUPCOPIESPORTS; else lx &= ~DUPCOPIESPORTS;
16418 		if (lx != us_useroptions)
16419 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, lx, VINTEGER);
16420 		j = (atofr(DiaGetText(dia, DDFN_ALLROTATION))*10/WHOLE) % 3600;
16421 		if (DiaGetControl(dia, DDFN_ALLTRANSPOSE) != 0) j += 3600;
16422 		if (j != pangle)
16423 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_placement_angle_key, j, VINTEGER);
16424 
16425 		/* set abbreviation info */
16426 		if (abbrevchanged)
16427 		{
16428 			for(i=0; i<MAXNODEFUNCTION; i++)
16429 			{
16430 				name = nodefunctionshortname(i);
16431 				if (estrcmp(name, shortnames[i]) == 0) shortnames[i][0] = 0;
16432 			}
16433 			setvalkey((INTBIG)net_tool, VTOOL, net_node_abbrev_key, (INTBIG)shortnames,
16434 				VSTRING|VISARRAY|(MAXNODEFUNCTION<<VLENGTHSH));
16435 		}
16436 		i = eatoi(DiaGetText(dia, DDFN_ABBREVLEN));
16437 		if (i != abbrevlen)
16438 			(void)setvalkey((INTBIG)net_tool, VTOOL, net_node_abbrevlen_key, i, VINTEGER);
16439 	}
16440 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
16441 		efree((CHAR *)np->temp1);
16442 	for(i=0; i<MAXNODEFUNCTION; i++)
16443 		efree((CHAR *)shortnames[i]);
16444 	efree((CHAR *)shortnames);
16445 	DiaDoneDialog(dia);
16446 	return(1);
16447 }
16448 
16449 /****************************** NODE INFORMATION DIALOGS ******************************/
16450 
16451 /* Resistance */
16452 static DIALOGITEM us_resistancedialogitems[] =
16453 {
16454  /*  1 */ {0, {40,192,64,256}, BUTTON, N_("OK")},
16455  /*  2 */ {0, {40,16,64,80}, BUTTON, N_("Cancel")},
16456  /*  3 */ {0, {8,24,24,118}, EDITTEXT, x_("")},
16457  /*  4 */ {0, {8,128,24,239}, POPUP, x_("")},
16458  /*  5 */ {0, {40,104,64,168}, BUTTON, N_("More...")}
16459 };
16460 static DIALOG us_resistancedialog = {{50,75,124,345}, N_("Resistance"), 0, 5, us_resistancedialogitems, 0, 0};
16461 
16462 /* special items for the "resistance" dialog: */
16463 #define DRES_RESISTANCE   3		/* resistance value (edit text) */
16464 #define DRES_UNITS        4		/* units (popup) */
16465 #define DRES_MORE         5		/* More... (button) */
16466 
us_resistancedlog(GEOM * geom,VARIABLE * var)16467 void us_resistancedlog(GEOM *geom, VARIABLE *var)
16468 {
16469 	INTBIG itemHit, i, dispunits;
16470 	float f;
16471 	CHAR *newlang[4], *initstr, *termstr, *pt;
16472 	UINTBIG des[TEXTDESCRIPTSIZE];
16473 	REGISTER void *dia;
16474 
16475 	/* display the resistance dialog box */
16476 	dia = DiaInitDialog(&us_resistancedialog);
16477 	if (dia == 0) return;
16478 
16479 	/* set the units popup */
16480 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_resistancenames[i]);
16481 	DiaSetPopup(dia, DRES_UNITS, 4, newlang);
16482 	dispunits = (us_electricalunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH;
16483 	DiaSetPopupEntry(dia, DRES_UNITS, dispunits);
16484 
16485 	/* show the resistance value */
16486 	if (var != NOVARIABLE) TDCOPY(des, var->textdescript); else
16487 	{
16488 		var = getvalkey((INTBIG)geom->entryaddr.ni, VNODEINST, -1, sch_resistancekey);
16489 		TDCLEAR(des);   defaulttextdescript(des, geom);  TDSETOFF(des, 0, 0);
16490 	}
16491 	if (var != NOVARIABLE)
16492 	{
16493 		pt = describesimplevariable(var);
16494 		if (isanumber(pt))
16495 		{
16496 			f = (float)eatof(describesimplevariable(var));
16497 			(void)allocstring(&initstr, displayedunits(f, VTUNITSRES, dispunits), us_tool->cluster);
16498 		} else
16499 		{
16500 			(void)allocstring(&initstr, pt, us_tool->cluster);
16501 		}
16502 	} else
16503 	{
16504 		f = figureunits(x_("100"), VTUNITSRES, dispunits);
16505 		(void)allocstring(&initstr, displayedunits(f, VTUNITSRES, dispunits), us_tool->cluster);
16506 	}
16507 	DiaSetText(dia, DRES_RESISTANCE, initstr);
16508 
16509 	/* loop until done */
16510 	for(;;)
16511 	{
16512 		itemHit = DiaNextHit(dia);
16513 		if (itemHit == CANCEL || itemHit == OK || itemHit == DRES_MORE) break;
16514 		if (itemHit == DRES_UNITS)
16515 		{
16516 			f = figureunits(DiaGetText(dia, DRES_RESISTANCE), VTUNITSRES, dispunits);
16517 			dispunits = DiaGetPopupEntry(dia, DRES_UNITS);
16518 			DiaSetText(dia, DRES_RESISTANCE, displayedunits(f, VTUNITSRES, dispunits));
16519 			continue;
16520 		}
16521 	}
16522 
16523 	termstr = DiaGetText(dia, DRES_RESISTANCE);
16524 	DiaDoneDialog(dia);
16525 	if (itemHit != CANCEL && namesame(initstr, termstr) != 0)
16526 	{
16527 		if (isanumber(termstr))
16528 		{
16529 			f = figureunits(termstr, VTUNITSRES, dispunits);
16530 			us_setfloatvariablevalue(geom, var->key /*sch_resistancekey*/, var, f);
16531 		} else
16532 		{
16533 			us_setvariablevalue(geom, var->key /*sch_resistancekey*/, termstr, VDISPLAY, des);
16534 		}
16535 	}
16536 	if (itemHit == DRES_MORE)
16537 	{
16538 		us_endchanges(NOWINDOWPART);
16539 		(void)us_showdlog(FALSE);
16540 	}
16541 }
16542 
16543 /* Capacitance */
16544 static DIALOGITEM us_capacitancedialogitems[] =
16545 {
16546  /*  1 */ {0, {40,176,64,240}, BUTTON, N_("OK")},
16547  /*  2 */ {0, {40,16,64,80}, BUTTON, N_("Cancel")},
16548  /*  3 */ {0, {8,16,24,110}, EDITTEXT, x_("")},
16549  /*  4 */ {0, {8,120,24,246}, POPUP, x_("")},
16550  /*  5 */ {0, {40,96,64,160}, BUTTON, N_("More...")}
16551 };
16552 static DIALOG us_capacitancedialog = {{50,75,123,330}, N_("Capacitance"), 0, 5, us_capacitancedialogitems, 0, 0};
16553 
16554 /* special items for the "capacitance" dialog: */
16555 #define DCAP_CAPACITANCE  3		/* capacitance value (edit text) */
16556 #define DCAP_UNITS        4		/* units (popup) */
16557 #define DCAP_MORE         5		/* More... (button) */
16558 
us_capacitancedlog(GEOM * geom,VARIABLE * var)16559 void us_capacitancedlog(GEOM *geom, VARIABLE *var)
16560 {
16561 	INTBIG itemHit, i, dispunits;
16562 	CHAR *newlang[6], *initstr, *termstr, *pt;
16563 	float f;
16564 	UINTBIG des[TEXTDESCRIPTSIZE];
16565 	REGISTER void *dia;
16566 
16567 	/* display the capacitance dialog box */
16568 	dia = DiaInitDialog(&us_capacitancedialog);
16569 	if (dia == 0) return;
16570 
16571 	/* set the units popup */
16572 	for(i=0; i<6; i++) newlang[i] = TRANSLATE(us_capacitancenames[i]);
16573 	DiaSetPopup(dia, DCAP_UNITS, 6, newlang);
16574 	dispunits = (us_electricalunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH;
16575 	DiaSetPopupEntry(dia, DCAP_UNITS, dispunits);
16576 
16577 	/* show the capacitance value */
16578 	if (var != NOVARIABLE) TDCOPY(des, var->textdescript); else
16579 	{
16580 		var = getvalkey((INTBIG)geom->entryaddr.ni, VNODEINST, -1, sch_capacitancekey);
16581 		TDCLEAR(des);   defaulttextdescript(des, geom);  TDSETOFF(des, 0, 0);
16582 	}
16583 	if (var != NOVARIABLE)
16584 	{
16585 		pt = describesimplevariable(var);
16586 		if (isanumber(pt))
16587 		{
16588 			f = (float)eatof(describesimplevariable(var));
16589 			(void)allocstring(&initstr, displayedunits(f, VTUNITSCAP, dispunits), us_tool->cluster);
16590 		} else
16591 		{
16592 			(void)allocstring(&initstr, pt, us_tool->cluster);
16593 		}
16594 	} else
16595 	{
16596 		f = figureunits(x_("100"), VTUNITSCAP, dispunits);
16597 		(void)allocstring(&initstr, displayedunits(f, VTUNITSCAP, dispunits), us_tool->cluster);
16598 	}
16599 	DiaSetText(dia, DCAP_CAPACITANCE, initstr);
16600 
16601 	/* loop until done */
16602 	for(;;)
16603 	{
16604 		itemHit = DiaNextHit(dia);
16605 		if (itemHit == CANCEL || itemHit == OK || itemHit == DCAP_MORE) break;
16606 		if (itemHit == DCAP_UNITS)
16607 		{
16608 			f = figureunits(DiaGetText(dia, DCAP_CAPACITANCE), VTUNITSCAP, dispunits);
16609 			dispunits = DiaGetPopupEntry(dia, DCAP_UNITS);
16610 			DiaSetText(dia, DCAP_CAPACITANCE, displayedunits(f, VTUNITSCAP, dispunits));
16611 			continue;
16612 		}
16613 	}
16614 
16615 	termstr = DiaGetText(dia, DCAP_CAPACITANCE);
16616 	DiaDoneDialog(dia);
16617 	if (itemHit != CANCEL && namesame(initstr, termstr) != 0)
16618 	{
16619 		if (isanumber(termstr))
16620 		{
16621 			f = figureunits(termstr, VTUNITSCAP, dispunits);
16622 			us_setfloatvariablevalue(geom, var->key /*sch_capacitancekey*/, var, f);
16623 		} else
16624 		{
16625 			us_setvariablevalue(geom, var->key /*sch_capacitancekey*/, termstr, VDISPLAY, des);
16626 		}
16627 	}
16628 	if (itemHit == DCAP_MORE)
16629 	{
16630 		us_endchanges(NOWINDOWPART);
16631 		(void)us_showdlog(FALSE);
16632 	}
16633 }
16634 
16635 /* Inductance */
16636 static DIALOGITEM us_inductancedialogitems[] =
16637 {
16638  /*  1 */ {0, {40,168,64,232}, BUTTON, N_("OK")},
16639  /*  2 */ {0, {40,8,64,72}, BUTTON, N_("Cancel")},
16640  /*  3 */ {0, {8,16,24,110}, EDITTEXT, x_("")},
16641  /*  4 */ {0, {8,120,24,237}, POPUP, x_("")},
16642  /*  5 */ {0, {40,88,64,152}, BUTTON, N_("More...")}
16643 };
16644 static DIALOG us_inductancedialog = {{50,75,126,321}, N_("Inductance"), 0, 5, us_inductancedialogitems, 0, 0};
16645 
16646 /* special items for the "inductance" dialog: */
16647 #define DIND_INDUCTANCE   3		/* inductance value (edit text) */
16648 #define DIND_UNITS        4		/* units (popup) */
16649 #define DIND_MORE         5		/* More... (button) */
16650 
us_inductancedlog(GEOM * geom,VARIABLE * var)16651 void us_inductancedlog(GEOM *geom, VARIABLE *var)
16652 {
16653 	INTBIG itemHit, i, dispunits;
16654 	CHAR *newlang[3], *initstr, *termstr, *pt;
16655 	float f;
16656 	UINTBIG des[TEXTDESCRIPTSIZE];
16657 	REGISTER void *dia;
16658 
16659 	/* display the inductance dialog box */
16660 	dia = DiaInitDialog(&us_inductancedialog);
16661 	if (dia == 0) return;
16662 
16663 	/* set the units popup */
16664 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_inductancenames[i]);
16665 	DiaSetPopup(dia, DIND_UNITS, 4, newlang);
16666 	dispunits = (us_electricalunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH;
16667 	DiaSetPopupEntry(dia, DIND_UNITS, dispunits);
16668 
16669 	/* show the inductance value */
16670 	if (var != NOVARIABLE) TDCOPY(des, var->textdescript); else
16671 	{
16672 		var = getvalkey((INTBIG)geom->entryaddr.ni, VNODEINST, -1, sch_inductancekey);
16673 		TDCLEAR(des);   defaulttextdescript(des, geom);  TDSETOFF(des, 0, 0);
16674 	}
16675 	if (var != NOVARIABLE)
16676 	{
16677 		pt = describesimplevariable(var);
16678 		if (isanumber(pt))
16679 		{
16680 			f = (float)eatof(describesimplevariable(var));
16681 			(void)allocstring(&initstr, displayedunits(f, VTUNITSIND, dispunits), us_tool->cluster);
16682 		} else
16683 		{
16684 			(void)allocstring(&initstr, pt, us_tool->cluster);
16685 		}
16686 	} else
16687 	{
16688 		f = figureunits(x_("100"), VTUNITSIND, dispunits);
16689 		(void)allocstring(&initstr, displayedunits(f, VTUNITSIND, dispunits), us_tool->cluster);
16690 	}
16691 	DiaSetText(dia, DIND_INDUCTANCE, initstr);
16692 
16693 	/* loop until done */
16694 	for(;;)
16695 	{
16696 		itemHit = DiaNextHit(dia);
16697 		if (itemHit == CANCEL || itemHit == OK || itemHit == DIND_MORE) break;
16698 		if (itemHit == DIND_UNITS)
16699 		{
16700 			f = figureunits(DiaGetText(dia, DIND_INDUCTANCE), VTUNITSIND, dispunits);
16701 			dispunits = DiaGetPopupEntry(dia, DIND_UNITS);
16702 			DiaSetText(dia, DIND_INDUCTANCE, displayedunits(f, VTUNITSIND, dispunits));
16703 			continue;
16704 		}
16705 	}
16706 
16707 	termstr = DiaGetText(dia, DIND_INDUCTANCE);
16708 	DiaDoneDialog(dia);
16709 	if (itemHit != CANCEL && namesame(initstr, termstr) != 0)
16710 	{
16711 		if (isanumber(termstr))
16712 		{
16713 			f = figureunits(termstr, VTUNITSIND, dispunits);
16714 			us_setfloatvariablevalue(geom, var->key /*sch_inductancekey*/, var, f);
16715 		} else
16716 		{
16717 			us_setvariablevalue(geom, var->key /*sch_inductancekey*/, termstr, VDISPLAY, des);
16718 		}
16719 	}
16720 	if (itemHit == DIND_MORE)
16721 	{
16722 		us_endchanges(NOWINDOWPART);
16723 		(void)us_showdlog(FALSE);
16724 	}
16725 }
16726 
16727 /* Area */
16728 static DIALOGITEM us_areadialogitems[] =
16729 {
16730  /*  1 */ {0, {40,184,64,248}, BUTTON, N_("OK")},
16731  /*  2 */ {0, {40,8,64,72}, BUTTON, N_("Cancel")},
16732  /*  3 */ {0, {8,80,24,174}, EDITTEXT, x_("")},
16733  /*  4 */ {0, {40,96,64,160}, BUTTON, N_("More...")}
16734 };
16735 static DIALOG us_areadialog = {{50,75,124,333}, N_("Area"), 0, 4, us_areadialogitems, 0, 0};
16736 
16737 /* special items for the "area" dialog: */
16738 #define DARE_AREA       3		/* area value (edit text) */
16739 #define DARE_MORE       4		/* More... (button) */
16740 
us_areadlog(NODEINST * ni)16741 void us_areadlog(NODEINST *ni)
16742 {
16743 	INTBIG itemHit, key, type;
16744 	static CHAR line[80];
16745 	REGISTER CHAR *pt;
16746 	REGISTER VARIABLE *var;
16747 	UINTBIG des[TEXTDESCRIPTSIZE];
16748 	REGISTER void *dia;
16749 
16750 	/* display the area dialog box */
16751 	if (ni->proto == sch_diodeprim)
16752 	{
16753 		(void)estrcpy(line, _("Diode area"));
16754 		key = sch_diodekey;
16755 	} else
16756 	{
16757 		(void)estrcpy(line, _("Transistor area"));
16758 		key = el_attrkey_area;
16759 	}
16760 	us_areadialog.movable = line;
16761 	dia = DiaInitDialog(&us_areadialog);
16762 	if (dia == 0) return;
16763 
16764 	type = VDISPLAY;
16765 	TDCLEAR(des);   defaulttextdescript(des, ni->geom);  TDSETOFF(des, 0, 0);
16766 	var = getvalkey((INTBIG)ni, VNODEINST, -1, key);
16767 	if (var == NOVARIABLE) pt = x_("10"); else
16768 	{
16769 		type = var->type;
16770 		TDCOPY(des, var->textdescript);
16771 		pt = describesimplevariable(var);
16772 	}
16773 	DiaSetText(dia, DARE_AREA, pt);
16774 
16775 	/* loop until done */
16776 	for(;;)
16777 	{
16778 		itemHit = DiaNextHit(dia);
16779 		if (itemHit == CANCEL || itemHit == OK || itemHit == DARE_MORE) break;
16780 	}
16781 
16782 	if (itemHit != CANCEL)
16783 	{
16784 		us_setvariablevalue(ni->geom, key, DiaGetText(dia, DARE_AREA), type, des);
16785 	}
16786 	DiaDoneDialog(dia);
16787 	if (itemHit == DARE_MORE)
16788 	{
16789 		us_endchanges(NOWINDOWPART);
16790 		(void)us_showdlog(FALSE);
16791 	}
16792 }
16793 
16794 /* Width/Length */
16795 static DIALOGITEM us_widlendialogitems[] =
16796 {
16797  /*  1 */ {0, {112,184,136,248}, BUTTON, N_("OK")},
16798  /*  2 */ {0, {112,8,136,72}, BUTTON, N_("Cancel")},
16799  /*  3 */ {0, {8,92,24,248}, EDITTEXT, x_("")},
16800  /*  4 */ {0, {8,8,24,83}, MESSAGE, N_("Width:")},
16801  /*  5 */ {0, {60,92,76,248}, EDITTEXT, x_("")},
16802  /*  6 */ {0, {60,8,76,84}, MESSAGE, N_("Length:")},
16803  /*  7 */ {0, {112,96,136,160}, BUTTON, N_("More")},
16804  /*  8 */ {0, {32,92,48,247}, POPUP, x_("")},
16805  /*  9 */ {0, {84,92,100,247}, POPUP, x_("")}
16806 };
16807 static DIALOG us_widlendialog = {{50,75,195,332}, N_("Transistor Information"), 0, 9, us_widlendialogitems, 0, 0};
16808 
16809 /* special items for the "width/length" dialog: */
16810 #define DWAL_WIDTH      3		/* Width value (edit text) */
16811 #define DWAL_LENGTH     5		/* Length value (edit text) */
16812 #define DWAL_LENGTH_L   6		/* Length label (stat text) */
16813 #define DWAL_MORE       7		/* More... (button) */
16814 #define DWAL_WIDLANG    8		/* Width language (popup) */
16815 #define DWAL_LENLANG    9		/* Length language (popup) */
16816 
us_widlendlog(NODEINST * ni)16817 void us_widlendlog(NODEINST *ni)
16818 {
16819 	INTBIG itemHit, widtype, lentype, widlang, lenlang;
16820 	CHAR *widstr, *lenstr, *pt, **languages;
16821 	REGISTER VARIABLE *var;
16822 	REGISTER NODEPROTO *np;
16823 	REGISTER void *dia;
16824 
16825 	/* display the width/length dialog box */
16826 	dia = DiaInitDialog(&us_widlendialog);
16827 	if (dia == 0) return;
16828 	languages = us_languagechoices();
16829 	DiaSetPopup(dia, DWAL_WIDLANG, 4, languages);
16830 
16831 	np = ni->proto;
16832 	if (np == mocmos_scalablentransprim || np == mocmos_scalableptransprim)
16833 	{
16834 		DiaDimItem(dia, DWAL_LENGTH);
16835 		DiaDimItem(dia, DWAL_LENLANG);
16836 		DiaDimItem(dia, DWAL_LENGTH_L);
16837 	} else
16838 	{
16839 		DiaUnDimItem(dia, DWAL_LENGTH);
16840 		DiaUnDimItem(dia, DWAL_LENLANG);
16841 		DiaUnDimItem(dia, DWAL_LENGTH_L);
16842 		DiaSetPopup(dia, DWAL_LENLANG, 4, languages);
16843 		lentype = VINTEGER|VDISPLAY;
16844 		var = getvalkeynoeval((INTBIG)ni, VNODEINST, -1, el_attrkey_length);
16845 		if (var == NOVARIABLE) (void)allocstring(&lenstr, x_("2"), us_tool->cluster); else
16846 		{
16847 			lentype = var->type;
16848 			lenlang = lentype & (VCODE1|VCODE2);
16849 			switch (lenlang)
16850 			{
16851 				case 0:     DiaSetPopupEntry(dia, DWAL_LENLANG, 0);   break;
16852 				case VTCL:  DiaSetPopupEntry(dia, DWAL_LENLANG, 1);   break;
16853 				case VLISP: DiaSetPopupEntry(dia, DWAL_LENLANG, 2);   break;
16854 				case VJAVA: DiaSetPopupEntry(dia, DWAL_LENLANG, 3);   break;
16855 			}
16856 			(void)allocstring(&lenstr, describevariable(var, -1, -1), us_tool->cluster);
16857 		}
16858 		DiaSetText(dia, DWAL_LENGTH, lenstr);
16859 	}
16860 
16861 	widtype = VINTEGER|VDISPLAY;
16862 	var = getvalkeynoeval((INTBIG)ni, VNODEINST, -1, el_attrkey_width);
16863 	if (var == NOVARIABLE) (void)allocstring(&widstr, x_("2"), us_tool->cluster); else
16864 	{
16865 		widtype = var->type;
16866 		widlang = widtype & (VCODE1|VCODE2);
16867 		switch (widlang)
16868 		{
16869 			case 0:     DiaSetPopupEntry(dia, DWAL_WIDLANG, 0);   break;
16870 			case VTCL:  DiaSetPopupEntry(dia, DWAL_WIDLANG, 1);   break;
16871 			case VLISP: DiaSetPopupEntry(dia, DWAL_WIDLANG, 2);   break;
16872 			case VJAVA: DiaSetPopupEntry(dia, DWAL_WIDLANG, 3);   break;
16873 		}
16874 		(void)allocstring(&widstr, describevariable(var, -1, -1), us_tool->cluster);
16875 	}
16876 	DiaSetText(dia, DWAL_WIDTH, widstr);
16877 
16878 	/* loop until done */
16879 	for(;;)
16880 	{
16881 		itemHit = DiaNextHit(dia);
16882 		if (itemHit == CANCEL || itemHit == OK || itemHit == DWAL_MORE) break;
16883 	}
16884 
16885 	if (itemHit != CANCEL)
16886 	{
16887 		if (np != mocmos_scalablentransprim && np != mocmos_scalableptransprim)
16888 		{
16889 			pt = DiaGetText(dia, DWAL_LENGTH);
16890 			lentype &= ~(VCODE1|VCODE2);
16891 			switch (DiaGetPopupEntry(dia, DWAL_LENLANG))
16892 			{
16893 				case 1: lentype |= VTCL;    break;
16894 				case 2: lentype |= VLISP;   break;
16895 				case 3: lentype |= VJAVA;   break;
16896 			}
16897 			if (estrcmp(pt, lenstr) != 0 || lenlang != (lentype & (VCODE1|VCODE2)))
16898 			{
16899 				us_setvariablevalue(ni->geom, el_attrkey_length, pt, lentype, 0);
16900 			}
16901 		}
16902 
16903 		pt = DiaGetText(dia, DWAL_WIDTH);
16904 		widtype &= ~(VCODE1|VCODE2);
16905 		switch (DiaGetPopupEntry(dia, DWAL_WIDLANG))
16906 		{
16907 			case 1: widtype |= VTCL;    break;
16908 			case 2: widtype |= VLISP;   break;
16909 			case 3: widtype |= VJAVA;   break;
16910 		}
16911 		if (estrcmp(pt, widstr) != 0 || widlang != (widtype & (VCODE1|VCODE2)))
16912 		{
16913 			us_setvariablevalue(ni->geom, el_attrkey_width, pt, widtype, 0);
16914 		}
16915 	}
16916 	DiaDoneDialog(dia);
16917 	if (itemHit == DWAL_MORE)
16918 	{
16919 		us_endchanges(NOWINDOWPART);
16920 		(void)us_showdlog(FALSE);
16921 	}
16922 }
16923 
16924 /****************************** NODE SIZE DIALOG ******************************/
16925 
16926 /* Node Size */
16927 static DIALOGITEM us_nodesizedialogitems[] =
16928 {
16929  /*  1 */ {0, {104,132,128,212}, BUTTON, N_("OK")},
16930  /*  2 */ {0, {104,4,128,84}, BUTTON, N_("Cancel")},
16931  /*  3 */ {0, {8,12,24,92}, MESSAGE|INACTIVE, N_("X Size:")},
16932  /*  4 */ {0, {36,12,52,92}, MESSAGE|INACTIVE, N_("Y Size:")},
16933  /*  5 */ {0, {8,100,24,200}, EDITTEXT, x_("")},
16934  /*  6 */ {0, {36,100,52,200}, EDITTEXT, x_("")},
16935  /*  7 */ {0, {64,4,96,212}, MESSAGE|INACTIVE, x_("")}
16936 };
16937 static DIALOG us_nodesizedialog = {{75,75,212,297}, N_("Set Node Size"), 0, 7, us_nodesizedialogitems, 0, 0};
16938 
16939 /* special items for the "node size" dialog: */
16940 #define DNOS_XSIZE       5		/* X size (edit text) */
16941 #define DNOS_YSIZE       6		/* Y size (edit text) */
16942 #define DNOS_EXTRAINFO   7		/* Extra message (stat text) */
16943 
us_nodesizedlog(CHAR * paramstart[])16944 INTBIG us_nodesizedlog(CHAR *paramstart[])
16945 {
16946 	INTBIG itemHit, allmanhattan;
16947 	INTBIG ret;
16948 	REGISTER INTBIG i;
16949 	static CHAR x[20], y[20];
16950 	REGISTER GEOM **list;
16951 	REGISTER NODEINST *ni;
16952 	REGISTER void *dia;
16953 
16954 	/* display the node size dialog box */
16955 	dia = DiaInitDialog(&us_nodesizedialog);
16956 	if (dia == 0) return(0);
16957 
16958 	/* see if there are nonmanhattan nodes selected */
16959 	allmanhattan = 1;
16960 	list = us_gethighlighted(WANTNODEINST, 0, 0);
16961 	for(i=0; list[i] != NOGEOM; i++)
16962 	{
16963 		ni = list[i]->entryaddr.ni;
16964 		if ((ni->rotation % 900) != 0) allmanhattan = 0;
16965 	}
16966 	if (allmanhattan == 0)
16967 	{
16968 		DiaSetText(dia, DNOS_EXTRAINFO,
16969 			_("Nonmanhattan nodes selected: sizing in unrotated directions"));
16970 	}
16971 
16972 	/* loop until done */
16973 	for(;;)
16974 	{
16975 		itemHit = DiaNextHit(dia);
16976 		if (itemHit == OK || itemHit == CANCEL) break;
16977 	}
16978 
16979 	ret = 0;
16980 	if (itemHit != CANCEL)
16981 	{
16982 		estrcpy(x, DiaGetText(dia, DNOS_XSIZE));
16983 		estrcpy(y, DiaGetText(dia, DNOS_YSIZE));
16984 		paramstart[ret++] = x;
16985 		paramstart[ret++] = y;
16986 		if (allmanhattan != 0) paramstart[ret++] = x_("use-transformation");
16987 	}
16988 	DiaDoneDialog(dia);
16989 	return(ret);
16990 }
16991 
16992 /****************************** SAVING OPTIONS WITH LIBRARIES DIALOG ******************************/
16993 
16994 /* Saving Options with Libraries */
16995 static DIALOGITEM us_optionsavingdialogitems[] =
16996 {
16997  /*  1 */ {0, {280,216,304,288}, BUTTON, N_("OK")},
16998  /*  2 */ {0, {280,12,304,84}, BUTTON, N_("Cancel")},
16999  /*  3 */ {0, {28,4,44,294}, MESSAGE, N_("Marked options are saved with the library,")},
17000  /*  4 */ {0, {92,4,268,294}, SCROLL, x_("")},
17001  /*  5 */ {0, {68,4,84,294}, MESSAGE, N_("Click an option to change its mark.")},
17002  /*  6 */ {0, {44,4,60,294}, MESSAGE, N_("and are restored when the library is read.")},
17003  /*  7 */ {0, {4,4,20,90}, MESSAGE, N_("For library:")},
17004  /*  8 */ {0, {4,92,20,294}, MESSAGE, x_("")}
17005 };
17006 static DIALOG us_optionsavingdialog = {{50,75,363,378}, N_("Saving Options with Libraries"), 0, 8, us_optionsavingdialogitems, 0, 0};
17007 
17008 /* special items for the "Option Saving" dialog: */
17009 #define DOPS_OPTIONLIST    4		/* List of options (scroll) */
17010 #define DOPS_LIBNAME       8		/* Library name (stat text) */
17011 
17012 /* this define should match the one in "dbvars.c" */
17013 #define SAVEDBITWORDS 2
17014 
us_optionsavingdlog(void)17015 INTBIG us_optionsavingdlog(void)
17016 {
17017 	INTBIG itemHit, i, len, opt, listlen;
17018 	INTBIG bits[SAVEDBITWORDS], savebits[SAVEDBITWORDS], origbits[SAVEDBITWORDS];
17019 	REGISTER VARIABLE *var;
17020 	CHAR *name, *msg;
17021 	REGISTER void *infstr;
17022 	REGISTER void *dia;
17023 
17024 	for(i=0; i<SAVEDBITWORDS; i++) savebits[i] = 0;
17025 	var = getval((INTBIG)el_curlib, VLIBRARY, -1, x_("LIB_save_options"));
17026 	if (var != NOVARIABLE)
17027 	{
17028 		if ((var->type&VISARRAY) == 0)
17029 		{
17030 			savebits[0] = var->addr;
17031 		} else
17032 		{
17033 			len = getlength(var);
17034 			for(i=0; i<len; i++) savebits[i] = ((INTBIG *)var->addr)[i];
17035 		}
17036 	}
17037 	for(i=0; i<SAVEDBITWORDS; i++) origbits[i] = savebits[i];
17038 
17039 	/* display the visibility dialog box */
17040 	dia = DiaInitDialog(&us_optionsavingdialog);
17041 	if (dia == 0) return(0);
17042 	DiaSetText(dia, DOPS_LIBNAME, el_curlib->libname);
17043 	DiaInitTextDialog(dia, DOPS_OPTIONLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
17044 		SCSELMOUSE|SCREPORT);
17045 	for(opt=0; ; opt++)
17046 	{
17047 		if (describeoptions(opt, &name, bits)) break;
17048 		infstr = initinfstr();
17049 		for(i=0; i<SAVEDBITWORDS; i++) if ((savebits[i]&bits[i]) != 0) break;
17050 		if (i < SAVEDBITWORDS) addtoinfstr(infstr, '>'); else
17051 			addtoinfstr(infstr, ' ');
17052 		addtoinfstr(infstr, ' ');
17053 		addstringtoinfstr(infstr, name);
17054 		DiaStuffLine(dia, DOPS_OPTIONLIST, returninfstr(infstr));
17055 	}
17056 	DiaSelectLine(dia, DOPS_OPTIONLIST, -1);
17057 
17058 	/* loop until done */
17059 	for(;;)
17060 	{
17061 		itemHit = DiaNextHit(dia);
17062 		if (itemHit == OK || itemHit == CANCEL) break;
17063 		if (itemHit == DOPS_OPTIONLIST)
17064 		{
17065 			i = DiaGetCurLine(dia, DOPS_OPTIONLIST);
17066 			msg = DiaGetScrollLine(dia, DOPS_OPTIONLIST, i);
17067 			if (*msg == ' ') *msg = '>'; else *msg = ' ';
17068 			DiaSetScrollLine(dia, DOPS_OPTIONLIST, i, msg);
17069 			DiaSelectLine(dia, DOPS_OPTIONLIST, -1);
17070 			continue;
17071 		}
17072 	}
17073 
17074 	if (itemHit == OK)
17075 	{
17076 		for(i=0; i<SAVEDBITWORDS; i++) savebits[i] = 0;
17077 		listlen = DiaGetNumScrollLines(dia, DOPS_OPTIONLIST);
17078 		for(opt=0; opt<listlen; opt++)
17079 		{
17080 			if (describeoptions(opt, &name, bits)) break;
17081 			msg = DiaGetScrollLine(dia, DOPS_OPTIONLIST, opt);
17082 			if (*msg == '>')
17083 			{
17084 				for(i=0; i<SAVEDBITWORDS; i++)
17085 					savebits[i] |= bits[i];
17086 			}
17087 		}
17088 		for(i=0; i<SAVEDBITWORDS; i++) if (origbits[i] != savebits[i]) break;
17089 		if (i < SAVEDBITWORDS)
17090 			(void)setval((INTBIG)el_curlib, VLIBRARY, x_("LIB_save_options"),
17091 				(INTBIG)savebits, VINTEGER|VISARRAY|(SAVEDBITWORDS<<VLENGTHSH));
17092 	}
17093 	DiaDoneDialog(dia);
17094 	return(0);
17095 }
17096 
17097 /****************************** SAVING OPTIONS DIALOGS ******************************/
17098 
17099 /* User Interface: Save Options */
17100 static DIALOGITEM us_saveoptsdialogitems[] =
17101 {
17102  /*  1 */ {0, {172,196,196,276}, BUTTON, N_("Yes")},
17103  /*  2 */ {0, {172,104,196,184}, BUTTON, N_("Cancel")},
17104  /*  3 */ {0, {172,12,196,92}, BUTTON, N_("No")},
17105  /*  4 */ {0, {8,8,24,276}, MESSAGE, N_("These Options have changed.  Save?")},
17106  /*  5 */ {0, {32,12,164,276}, SCROLL, x_("")}
17107 };
17108 static DIALOG us_saveoptsdialog = {{75,75,280,360}, N_("Save Options?"), 0, 5, us_saveoptsdialogitems, 0, 0};
17109 
17110 /* special items for the "save options" command: */
17111 #define DSVO_YES      1		/* Yes (button) */
17112 #define DSVO_CANCEL   2		/* Cancel (button) */
17113 #define DSVO_NO       3		/* No (button) */
17114 #define DSVO_CHANGED  5		/* List of changed options (scroll) */
17115 
17116 /*
17117  * Routine to prompt the user to save options.  Returns true if the program should not
17118  * exit (because "cancel" was hit).  If "atquit" is TRUE, this is a prompt at exit time.
17119  */
us_saveoptdlog(BOOLEAN atquit)17120 BOOLEAN us_saveoptdlog(BOOLEAN atquit)
17121 {
17122 	INTBIG itemHit;
17123 	REGISTER void *dia;
17124 
17125 	/* display the quit dialog box */
17126 	if (atquit) us_saveoptsdialog.movable = _("Save Options?"); else
17127 		us_saveoptsdialog.movable = _("Also Save Options?");
17128 	dia = DiaInitDialog(&us_saveoptsdialog);
17129 	if (dia == 0) return(FALSE);
17130 	DiaInitTextDialog(dia, DSVO_CHANGED, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
17131 		SCHORIZBAR);
17132 
17133 	/* load the changed options */
17134 	explainoptionchanges(DSVO_CHANGED, dia);
17135 	DiaSelectLine(dia, DSVO_CHANGED, -1);
17136 
17137 	/* loop until done */
17138 	for(;;)
17139 	{
17140 		itemHit = DiaNextHit(dia);
17141 		if (itemHit == DSVO_YES || itemHit == DSVO_CANCEL || itemHit == DSVO_NO) break;
17142 	}
17143 
17144 	if (itemHit == DSVO_YES)
17145 		us_saveoptions();
17146 	DiaDoneDialog(dia);
17147 	if (itemHit == DSVO_CANCEL) return(TRUE);
17148 	return(FALSE);
17149 }
17150 
17151 
17152 /* Options Being Saved */
17153 static DIALOGITEM us_optsavedialogitems[] =
17154 {
17155  /*  1 */ {0, {240,205,264,285}, BUTTON, N_("OK")},
17156  /*  2 */ {0, {240,16,264,96}, BUTTON, N_("Cancel")},
17157  /*  3 */ {0, {24,4,208,300}, SCROLL, x_("")},
17158  /*  4 */ {0, {4,4,20,276}, MESSAGE, N_("These options are being saved:")},
17159  /*  5 */ {0, {212,4,228,300}, CHECK, N_("Only show options changed this session")}
17160 };
17161 static DIALOG us_optsavedialog = {{75,75,348,385}, N_("Options Being Saved"), 0, 5, us_optsavedialogitems, 0, 0};
17162 
17163 /* special items for the "options being saved" command: */
17164 #define DOBS_LIST     3		/* List of options (scroll) */
17165 #define DOBS_CHANGED  5		/* Only show changed options (check) */
17166 
us_examineoptionsdlog(void)17167 INTBIG us_examineoptionsdlog(void)
17168 {
17169 	INTBIG itemHit;
17170 	BOOLEAN onlychanged;
17171 	REGISTER void *dia;
17172 
17173 	/* display the examine options dialog box */
17174 	dia = DiaInitDialog(&us_optsavedialog);
17175 	if (dia == 0) return(0);
17176 	DiaInitTextDialog(dia, DOBS_LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
17177 		SCHORIZBAR);
17178 
17179 	/* load the changed options */
17180 	onlychanged = FALSE;
17181 	explainsavedoptions(DOBS_LIST, onlychanged, dia);
17182 	DiaSelectLine(dia, DOBS_LIST, -1);
17183 
17184 	/* loop until done */
17185 	for(;;)
17186 	{
17187 		itemHit = DiaNextHit(dia);
17188 		if (itemHit == OK || itemHit == CANCEL) break;
17189 		if (itemHit == DOBS_CHANGED)
17190 		{
17191 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
17192 			onlychanged = !onlychanged;
17193 			DiaLoadTextDialog(dia, DOBS_LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
17194 			explainsavedoptions(DOBS_LIST, onlychanged, dia);
17195 			DiaSelectLine(dia, DOBS_LIST, -1);
17196 			continue;
17197 		}
17198 	}
17199 
17200 	DiaDoneDialog(dia);
17201 	return(0);
17202 }
17203 
17204 /* Find Options */
17205 static DIALOGITEM us_findoptdialogitems[] =
17206 {
17207  /*  1 */ {0, {292,8,316,88}, BUTTON, N_("Find")},
17208  /*  2 */ {0, {24,4,288,372}, SCROLL, x_("")},
17209  /*  3 */ {0, {4,4,20,84}, MESSAGE, N_("Options:")},
17210  /*  4 */ {0, {292,292,316,372}, BUTTON, N_("Done")},
17211  /*  5 */ {0, {296,92,312,288}, EDITTEXT, x_("")}
17212 };
17213 static DIALOG us_findoptdialog = {{75,75,400,457}, N_("Finding Options"), 0, 5, us_findoptdialogitems, 0, 0};
17214 
17215 /* special items for the "find options" command: */
17216 #define DFIO_FIND     1		/* Find this option (button) */
17217 #define DFIO_LIST     2		/* List of options (scroll) */
17218 #define DFIO_DONE     4		/* Done (button) */
17219 #define DFIO_SEARCH   5		/* string to search for (edit text) */
17220 
us_findoptionsdlog(void)17221 INTBIG us_findoptionsdlog(void)
17222 {
17223 	INTBIG itemHit, curline, startline, searchstringlen, i, len;
17224 	REGISTER void *dia;
17225 	REGISTER CHAR *searchstring, *pt;
17226 
17227 	/* display the find options dialog box */
17228 	dia = DiaInitDialog(&us_findoptdialog);
17229 	if (dia == 0) return(0);
17230 	DiaInitTextDialog(dia, DFIO_LIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
17231 		SCHORIZBAR);
17232 	listalloptions(DFIO_LIST, dia);
17233 	curline = 0;
17234 	DiaSelectLine(dia, DFIO_LIST, curline);
17235 
17236 	/* loop until done */
17237 	for(;;)
17238 	{
17239 		itemHit = DiaNextHit(dia);
17240 		if (itemHit == DFIO_DONE) break;
17241 		if (itemHit == DFIO_FIND)
17242 		{
17243 			searchstring = DiaGetText(dia, DFIO_SEARCH);
17244 			searchstringlen = estrlen(searchstring);
17245 			startline = curline;
17246 			for(;;)
17247 			{
17248 				curline++;
17249 				if (curline == startline)
17250 				{
17251 					ttybeep(SOUNDBEEP, FALSE);
17252 					break;
17253 				}
17254 				pt = DiaGetScrollLine(dia, DFIO_LIST, curline);
17255 				if (*pt == 0)
17256 				{
17257 					curline = -1;
17258 					continue;
17259 				}
17260 
17261 				len = estrlen(pt);
17262 				for(i=0; i<=len-searchstringlen; i++)
17263 					if (namesamen(searchstring, &pt[i], searchstringlen) == 0) break;
17264 				if (i <= len-searchstringlen)
17265 				{
17266 					DiaSelectLine(dia, DFIO_LIST, curline);
17267 					break;
17268 				}
17269 			}
17270 			continue;
17271 		}
17272 	}
17273 
17274 	DiaDoneDialog(dia);
17275 	return(0);
17276 }
17277 
17278 /****************************** OUTLINE INFO DIALOG ******************************/
17279 
17280 /* Outline Info */
17281 static DIALOGITEM us_outlinedialogitems[] =
17282 {
17283  /*  1 */ {0, {76,208,100,272}, BUTTON, N_("OK")},
17284  /*  2 */ {0, {20,208,44,272}, BUTTON, N_("Cancel")},
17285  /*  3 */ {0, {8,8,168,192}, SCROLL, x_("")},
17286  /*  4 */ {0, {184,8,200,28}, MESSAGE, N_("X:")},
17287  /*  5 */ {0, {184,32,200,104}, EDITTEXT, x_("")},
17288  /*  6 */ {0, {216,8,232,28}, MESSAGE, N_("Y:")},
17289  /*  7 */ {0, {216,32,232,104}, EDITTEXT, x_("")},
17290  /*  8 */ {0, {208,160,232,272}, BUTTON, N_("Duplicate Point")},
17291  /*  9 */ {0, {176,160,200,272}, BUTTON, N_("Delete Point")},
17292  /* 10 */ {0, {132,208,156,272}, BUTTON, N_("Apply")}
17293 };
17294 static DIALOG us_outlinedialog = {{50,75,291,356}, N_("Outline Information"), 0, 10, us_outlinedialogitems, 0, 0};
17295 
17296 /* special items for the "outline" dialog: */
17297 #define DOLI_POINTS     3		/* Points (scroll) */
17298 #define DOLI_XVALUE     5		/* X (edit text) */
17299 #define DOLI_YVALUE     7		/* Y (edit text) */
17300 #define DOLI_DUPLICATE  8		/* duplicate (button) */
17301 #define DOLI_DELETE     9		/* delete (button) */
17302 #define DOLI_APPLY     10		/* apply (button) */
17303 
us_tracedlog(void)17304 INTBIG us_tracedlog(void)
17305 {
17306 	INTBIG itemHit, len, i, j, space, lambda;
17307 	BOOLEAN changed;
17308 	INTBIG *pts, *newpts, x, y;
17309 	CHAR lne[256];
17310 	HIGHLIGHT *high;
17311 	REGISTER NODEINST *ni;
17312 	REGISTER VARIABLE *var;
17313 	REGISTER void *dia;
17314 
17315 	/* make sure there is a highlighted node with outline information */
17316 	high = us_getonehighlight();
17317 	if (high == NOHIGHLIGHT) return(0);
17318 	if ((high->status&HIGHTYPE) != HIGHFROM) return(0);
17319 	if (!high->fromgeom->entryisnode) return(0);
17320 	ni = (NODEINST *)high->fromgeom->entryaddr.ni;
17321 	if ((ni->proto->userbits&HOLDSTRACE) == 0) return(0);
17322 	var = gettrace(ni);
17323 	lambda = lambdaofnode(ni);
17324 
17325 	/* display the outline dialog box */
17326 	dia = DiaInitDialog(&us_outlinedialog);
17327 	if (dia == 0) return(0);
17328 	DiaInitTextDialog(dia, DOLI_POINTS, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
17329 		SCSELMOUSE|SCREPORT);
17330 
17331 	/* copy outline data and display it */
17332 	if (var == NOVARIABLE) len = 0; else len = getlength(var) / 2;
17333 	x = (ni->highx + ni->lowx) / 2;
17334 	y = (ni->highy + ni->lowy) / 2;
17335 	space = len+1;
17336 	pts = (INTBIG *)emalloc(space * 2 * SIZEOFINTBIG, el_tempcluster);
17337 	for(i=0; i<len; i++)
17338 	{
17339 		pts[i*2] = ((INTBIG *)var->addr)[i*2] + x;
17340 		pts[i*2+1] = ((INTBIG *)var->addr)[i*2+1] + y;
17341 		(void)esnprintf(lne, 256, x_("%ld: (%s, %s)"), i, latoa(pts[i*2], lambda),
17342 			latoa(pts[i*2+1], lambda));
17343 		DiaStuffLine(dia, DOLI_POINTS, lne);
17344 	}
17345 	if (len == 0) DiaSelectLine(dia, DOLI_POINTS, -1); else
17346 	{
17347 		DiaSelectLine(dia, DOLI_POINTS, 0);
17348 		DiaSetText(dia, -DOLI_XVALUE, latoa(pts[0], lambda));
17349 		DiaSetText(dia, DOLI_YVALUE, latoa(pts[1], lambda));
17350 	}
17351 
17352 	/* loop until done */
17353 	changed = FALSE;
17354 	for(;;)
17355 	{
17356 		itemHit = DiaNextHit(dia);
17357 		if (itemHit == CANCEL || itemHit == OK) break;
17358 		if (itemHit == DOLI_POINTS)
17359 		{
17360 			/* load this point */
17361 			i = DiaGetCurLine(dia, DOLI_POINTS);
17362 			if (i < 0 || i >= len) continue;
17363 			DiaSetText(dia, DOLI_XVALUE, latoa(pts[i*2], lambda));
17364 			DiaSetText(dia, DOLI_YVALUE, latoa(pts[i*2+1], lambda));
17365 			continue;
17366 		}
17367 		if (itemHit == DOLI_DUPLICATE)
17368 		{
17369 			/* duplicate point */
17370 			changed = TRUE;
17371 			if (len == 0)
17372 			{
17373 				pts[0] = pts[1] = 0;
17374 				(void)esnprintf(lne, 256, x_("%d: (%s, %s)"), 0, latoa(pts[0], lambda),
17375 					latoa(pts[1], lambda));
17376 				DiaSetScrollLine(dia, DOLI_POINTS, 0, lne);
17377 				len++;
17378 				continue;
17379 			}
17380 
17381 			if (len >= space)
17382 			{
17383 				newpts = (INTBIG *)emalloc((len+1) * 2 * SIZEOFINTBIG, el_tempcluster);
17384 				if (newpts == 0) continue;
17385 				for(i=0; i<len; i++)
17386 				{
17387 					newpts[i*2] = pts[i*2];
17388 					newpts[i*2+1] = pts[i*2+1];
17389 				}
17390 				efree((CHAR *)pts);
17391 				pts = newpts;
17392 				space = len + 1;
17393 			}
17394 			i = DiaGetCurLine(dia, DOLI_POINTS);
17395 			for(j=len; j>i; j--)
17396 			{
17397 				pts[j*2] = pts[(j-1)*2];
17398 				pts[j*2+1] = pts[(j-1)*2+1];
17399 				(void)esnprintf(lne, 256, x_("%ld: (%s, %s)"), j, latoa(pts[j*2], lambda),
17400 					latoa(pts[j*2+1], lambda));
17401 				DiaSetScrollLine(dia, DOLI_POINTS, j, lne);
17402 			}
17403 			len++;
17404 			continue;
17405 		}
17406 		if (itemHit == DOLI_DELETE)
17407 		{
17408 			/* delete point */
17409 			changed = TRUE;
17410 			if (len <= 1) continue;
17411 			i = DiaGetCurLine(dia, DOLI_POINTS);
17412 			for(j=i; j<len-1; j++)
17413 			{
17414 				pts[j*2] = pts[(j+1)*2];
17415 				pts[j*2+1] = pts[(j+1)*2+1];
17416 				(void)esnprintf(lne, 256, x_("%ld: (%s, %s)"), j, latoa(pts[j*2], lambda),
17417 					latoa(pts[j*2+1], lambda));
17418 				DiaSetScrollLine(dia, DOLI_POINTS, j, lne);
17419 			}
17420 			DiaSetScrollLine(dia, DOLI_POINTS, len-1, x_(""));
17421 			len--;
17422 			if (i == len) DiaSelectLine(dia, DOLI_POINTS, i-1);
17423 			continue;
17424 		}
17425 		if (itemHit == DOLI_XVALUE || itemHit == DOLI_YVALUE)
17426 		{
17427 			/* change to X or Y coordinates */
17428 			i = DiaGetCurLine(dia, DOLI_POINTS);
17429 			if (i < 0) continue;
17430 			x = atola(DiaGetText(dia, DOLI_XVALUE), lambda);
17431 			y = atola(DiaGetText(dia, DOLI_YVALUE), lambda);
17432 			if (pts[i*2] == x && pts[i*2+1] == y) continue;
17433 			changed = TRUE;
17434 			pts[i*2] = x;   pts[i*2+1] = y;
17435 			(void)esnprintf(lne, 256, x_("%ld: (%s, %s)"), i, latoa(pts[i*2], lambda),
17436 				latoa(pts[i*2+1], lambda));
17437 			DiaSetScrollLine(dia, DOLI_POINTS, i, lne);
17438 			continue;
17439 		}
17440 		if (itemHit == DOLI_APPLY)
17441 		{
17442 			/* apply */
17443 			us_pushhighlight();
17444 			us_clearhighlightcount();
17445 			us_settrace(ni, pts, len);
17446 			us_pophighlight(TRUE);
17447 			us_showallhighlight();
17448 			us_endchanges(NOWINDOWPART);
17449 			changed = FALSE;
17450 			continue;
17451 		}
17452 	}
17453 
17454 	if (itemHit != CANCEL && changed)
17455 	{
17456 		us_pushhighlight();
17457 		us_clearhighlightcount();
17458 		us_settrace(ni, pts, len);
17459 		us_pophighlight(TRUE);
17460 	}
17461 	DiaDoneDialog(dia);
17462 	efree((CHAR *)pts);
17463 	return(0);
17464 }
17465 
17466 /****************************** PORT CREATION DIALOG ******************************/
17467 
17468 /* New export */
17469 static DIALOGITEM us_portdialogitems[] =
17470 {
17471  /*  1 */ {0, {108,256,132,328}, BUTTON, N_("OK")},
17472  /*  2 */ {0, {108,32,132,104}, BUTTON, N_("Cancel")},
17473  /*  3 */ {0, {8,116,24,340}, EDITTEXT, x_("")},
17474  /*  4 */ {0, {32,176,48,340}, POPUP, x_("")},
17475  /*  5 */ {0, {8,8,24,112}, MESSAGE, N_("Export name:")},
17476  /*  6 */ {0, {56,8,72,128}, CHECK, N_("Always drawn")},
17477  /*  7 */ {0, {32,8,48,175}, MESSAGE, N_("Export characteristics:")},
17478  /*  8 */ {0, {80,8,96,128}, CHECK, N_("Body only")},
17479  /*  9 */ {0, {56,176,72,340}, MESSAGE, N_("Reference export:")},
17480  /* 10 */ {0, {80,176,96,340}, EDITTEXT, x_("")}
17481 };
17482 static DIALOG us_portdialog = {{50,75,191,425}, N_("Create Export on Highlighted Node"), 0, 10, us_portdialogitems, 0, 0};
17483 
17484 /* special items for the "Create Export" dialog: */
17485 #define DCEX_PORTNAME    3		/* Export name (edit text) */
17486 #define DCEX_PORTTYPE    4		/* Export characteristics (popup) */
17487 #define DCEX_ALWAYSDRAWN 6		/* Always drawn (check) */
17488 #define DCEX_BODYONLY    8		/* Body only (check) */
17489 #define DCEX_REFPORT_L   9		/* Reference export label (stat text) */
17490 #define DCEX_REFPORT    10		/* Reference export (edit text) */
17491 
us_portdlog(void)17492 INTBIG us_portdlog(void)
17493 {
17494 	INTBIG itemHit, i, count, bits, mask;
17495 	UINTBIG exportchar;
17496 	REGISTER PORTPROTO *pp;
17497 	static INTBIG lastchar = 0;
17498 	REGISTER NODEINST *ni;
17499 	CHAR *newlang[NUMPORTCHARS], *params[20], *refname, *pt, *portname;
17500 	REGISTER void *dia;
17501 
17502 	/* get the selected node */
17503 	ni = (NODEINST *)us_getobject(VNODEINST, FALSE);
17504 	if (ni == NONODEINST) return(0);
17505 
17506 	/* disallow port action if lock is on */
17507 	if (us_cantedit(ni->parent, NONODEINST, TRUE)) return(0);
17508 
17509 	/* display the port dialog box */
17510 	dia = DiaInitDialog(&us_portdialog);
17511 	if (dia == 0) return(0);
17512 	DiaSetText(dia, -DCEX_PORTNAME, x_(""));
17513 	for(i=0; i<NUMPORTCHARS; i++) newlang[i] = TRANSLATE(us_exportcharnames[i]);
17514 	DiaSetPopup(dia, DCEX_PORTTYPE, NUMPORTCHARS, newlang);
17515 	DiaSetPopupEntry(dia, DCEX_PORTTYPE, lastchar);
17516 	exportchar = us_exportcharlist[lastchar];
17517 	if (exportchar == REFOUTPORT || exportchar == REFINPORT ||
17518 		exportchar == REFBASEPORT)
17519 	{
17520 		DiaUnDimItem(dia, DCEX_REFPORT_L);
17521 		DiaUnDimItem(dia, DCEX_REFPORT);
17522 	} else
17523 	{
17524 		DiaDimItem(dia, DCEX_REFPORT_L);
17525 		DiaDimItem(dia, DCEX_REFPORT);
17526 	}
17527 
17528 	/* loop until done */
17529 	for(;;)
17530 	{
17531 		itemHit = DiaNextHit(dia);
17532 		if (itemHit == CANCEL) break;
17533 		if (itemHit == OK && DiaValidEntry(dia, DCEX_PORTNAME)) break;
17534 		if (itemHit == DCEX_PORTTYPE)
17535 		{
17536 			lastchar = DiaGetPopupEntry(dia, DCEX_PORTTYPE);
17537 			exportchar = us_exportcharlist[lastchar];
17538 			if (exportchar == REFOUTPORT || exportchar == REFINPORT ||
17539 				exportchar == REFBASEPORT)
17540 			{
17541 				DiaUnDimItem(dia, DCEX_REFPORT_L);
17542 				DiaUnDimItem(dia, DCEX_REFPORT);
17543 			} else
17544 			{
17545 				DiaDimItem(dia, DCEX_REFPORT_L);
17546 				DiaDimItem(dia, DCEX_REFPORT);
17547 			}
17548 		}
17549 		if (itemHit == DCEX_ALWAYSDRAWN || itemHit == DCEX_BODYONLY)
17550 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
17551 	}
17552 
17553 	if (itemHit != CANCEL)
17554 	{
17555 		count = 0;
17556 		if (lastchar > 0) params[count++] = us_exportintnames[lastchar];
17557 		if (DiaGetControl(dia, DCEX_ALWAYSDRAWN) != 0) params[count++] = x_("always-drawn");
17558 		if (DiaGetControl(dia, DCEX_BODYONLY) != 0) params[count++] = x_("body-only");
17559 		exportchar = us_exportcharlist[lastchar];
17560 		if (exportchar == REFOUTPORT || exportchar == REFINPORT ||
17561 			exportchar == REFBASEPORT)
17562 		{
17563 			refname = DiaGetText(dia, DCEX_REFPORT);
17564 			while (*refname == ' ') refname++;
17565 			if (*refname != 0)
17566 			{
17567 				params[count++] = x_("refname");
17568 				params[count++] = refname;
17569 			}
17570 		} else refname = 0;
17571 
17572 		pt = DiaGetText(dia, DCEX_PORTNAME);
17573 		while (*pt == ' ') pt++;
17574 		if (*pt == 0) us_abortcommand(_("Null name")); else
17575 		{
17576 			/* find a unique port name */
17577 			portname = us_uniqueportname(pt, ni->parent);
17578 			if (namesame(portname, pt) != 0)
17579 				ttyputmsg(_("Already a port called %s, calling this %s"), pt, portname);
17580 
17581 			/* get the specification details */
17582 			pp = us_portdetails(NOPORTPROTO, count, params, ni, &bits, &mask, FALSE, pt, &refname);
17583 			if (pp != NOPORTPROTO)
17584 			{
17585 				/* save highlighting */
17586 				us_pushhighlight();
17587 				us_clearhighlightcount();
17588 
17589 				/* make the port */
17590 				pp = us_makenewportproto(ni->parent, ni, pp, portname, mask, bits, pp->textdescript);
17591 				if (*refname != 0)
17592 					setval((INTBIG)pp, VPORTPROTO, x_("EXPORT_reference_name"), (INTBIG)refname, VSTRING);
17593 
17594 				/* restore highlighting */
17595 				us_pophighlight(FALSE);
17596 			}
17597 		}
17598 	}
17599 	DiaDoneDialog(dia);
17600 	return(0);
17601 }
17602 /****************************** PORT DISPLAY DIALOG ******************************/
17603 
17604 /* Port Display Options */
17605 static DIALOGITEM us_portdisplaydialogitems[] =
17606 {
17607  /*  1 */ {0, {148,208,172,272}, BUTTON, N_("OK")},
17608  /*  2 */ {0, {148,20,172,84}, BUTTON, N_("Cancel")},
17609  /*  3 */ {0, {36,8,52,123}, RADIO, N_("Full Names")},
17610  /*  4 */ {0, {60,8,76,123}, RADIO, N_("Short Names")},
17611  /*  5 */ {0, {84,8,100,123}, RADIO, N_("Crosses")},
17612  /*  6 */ {0, {8,8,24,151}, MESSAGE, N_("Ports (on instances):")},
17613  /*  7 */ {0, {36,156,52,271}, RADIO, N_("Full Names")},
17614  /*  8 */ {0, {60,156,76,271}, RADIO, N_("Short Names")},
17615  /*  9 */ {0, {84,156,100,271}, RADIO, N_("Crosses")},
17616  /* 10 */ {0, {8,156,24,295}, MESSAGE, N_("Exports (in cells):")},
17617  /* 11 */ {0, {116,8,132,280}, CHECK, N_("Move node with export name")},
17618  /* 12 */ {0, {108,8,109,292}, DIVIDELINE, x_("")}
17619 };
17620 static DIALOG us_portdisplaydialog = {{133,131,314,435}, N_("Port and Export Options"), 0, 12, us_portdisplaydialogitems, 0, 0};
17621 
17622 /* special items for the "Port Display" dialog: */
17623 #define DPDP_PFULLNAMES    3		/* Ports: Full Names (radio) */
17624 #define DPDP_PSHORTNAMES   4		/* Ports: Short Names (radio) */
17625 #define DPDP_PCROSSNAMES   5		/* Ports: Crosses (radio) */
17626 #define DPDP_EFULLNAMES    7		/* Export: Full Names (radio) */
17627 #define DPDP_ESHORTNAMES   8		/* Export: Short Names (radio) */
17628 #define DPDP_ECROSSNAMES   9		/* Export: Crosses (radio) */
17629 #define DPDP_MOVENODE     11		/* Move node with port (check) */
17630 
us_portdisplaydlog(void)17631 INTBIG us_portdisplaydlog(void)
17632 {
17633 	REGISTER INTBIG itemHit, labels, newoptions;
17634 	REGISTER void *dia;
17635 
17636 	/* display the port labels dialog */
17637 	if (us_needwindow()) return(0);
17638 	dia = DiaInitDialog(&us_portdisplaydialog);
17639 	if (dia == 0) return(0);
17640 	labels = us_useroptions & (PORTLABELS|EXPORTLABELS);
17641 	switch (labels&PORTLABELS)
17642 	{
17643 		case PORTSFULL:  DiaSetControl(dia, DPDP_PFULLNAMES, 1);   break;
17644 		case PORTSSHORT: DiaSetControl(dia, DPDP_PSHORTNAMES, 1);  break;
17645 		case PORTSCROSS: DiaSetControl(dia, DPDP_PCROSSNAMES, 1);  break;
17646 	}
17647 	switch (labels&EXPORTLABELS)
17648 	{
17649 		case EXPORTSFULL:  DiaSetControl(dia, DPDP_EFULLNAMES, 1);   break;
17650 		case EXPORTSSHORT: DiaSetControl(dia, DPDP_ESHORTNAMES, 1);  break;
17651 		case EXPORTSCROSS: DiaSetControl(dia, DPDP_ECROSSNAMES, 1);  break;
17652 	}
17653 	if ((us_useroptions&MOVENODEWITHEXPORT) != 0)
17654 		DiaSetControl(dia, DPDP_MOVENODE, 1);
17655 	for(;;)
17656 	{
17657 		itemHit = DiaNextHit(dia);
17658 		if (itemHit == CANCEL || itemHit == OK) break;
17659 		if (itemHit == DPDP_MOVENODE)
17660 		{
17661 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
17662 			continue;
17663 		}
17664 		if (itemHit == DPDP_PFULLNAMES || itemHit == DPDP_PSHORTNAMES ||
17665 			itemHit == DPDP_PCROSSNAMES)
17666 		{
17667 			DiaSetControl(dia, DPDP_PFULLNAMES, 0);
17668 			DiaSetControl(dia, DPDP_PSHORTNAMES, 0);
17669 			DiaSetControl(dia, DPDP_PCROSSNAMES, 0);
17670 			DiaSetControl(dia, itemHit, 1);
17671 			continue;
17672 		}
17673 		if (itemHit == DPDP_EFULLNAMES || itemHit == DPDP_ESHORTNAMES ||
17674 			itemHit == DPDP_ECROSSNAMES)
17675 		{
17676 			DiaSetControl(dia, DPDP_EFULLNAMES, 0);
17677 			DiaSetControl(dia, DPDP_ESHORTNAMES, 0);
17678 			DiaSetControl(dia, DPDP_ECROSSNAMES, 0);
17679 			DiaSetControl(dia, itemHit, 1);
17680 			continue;
17681 		}
17682 	}
17683 	newoptions = us_useroptions & ~(PORTLABELS | EXPORTLABELS | MOVENODEWITHEXPORT);
17684 	if (DiaGetControl(dia, DPDP_PFULLNAMES) != 0) newoptions |= PORTSFULL; else
17685 		if (DiaGetControl(dia, DPDP_PSHORTNAMES) != 0) newoptions |= PORTSSHORT; else
17686 			newoptions |= PORTSCROSS;
17687 	if (DiaGetControl(dia, DPDP_EFULLNAMES) != 0) newoptions |= EXPORTSFULL; else
17688 		if (DiaGetControl(dia, DPDP_ESHORTNAMES) != 0) newoptions |= EXPORTSSHORT; else
17689 			newoptions |= EXPORTSCROSS;
17690 	if (DiaGetControl(dia, DPDP_MOVENODE) != 0) newoptions |= MOVENODEWITHEXPORT;
17691 	DiaDoneDialog(dia);
17692 	if (itemHit == OK)
17693 	{
17694 		if (us_useroptions != newoptions)
17695 		{
17696 			startobjectchange((INTBIG)us_tool, VTOOL);
17697 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, newoptions, VINTEGER);
17698 			endobjectchange((INTBIG)us_tool, VTOOL);
17699 		}
17700 	}
17701 	return(0);
17702 }
17703 
17704 /****************************** PRINT OPTIONS DIALOG ******************************/
17705 
17706 /* Printing Options */
17707 static DIALOGITEM us_printingoptdialogitems[] =
17708 {
17709  /*  1 */ {0, {44,400,68,458}, BUTTON, N_("OK")},
17710  /*  2 */ {0, {8,400,32,458}, BUTTON, N_("Cancel")},
17711  /*  3 */ {0, {32,8,48,204}, RADIO, N_("Plot only Highlighted Area")},
17712  /*  4 */ {0, {8,8,24,142}, RADIO, N_("Plot Entire Cell")},
17713  /*  5 */ {0, {108,104,124,220}, CHECK, N_("Encapsulated")},
17714  /*  6 */ {0, {8,228,24,383}, CHECK, N_("Plot Date In Corner")},
17715  /*  7 */ {0, {308,108,324,166}, RADIO, N_("HPGL")},
17716  /*  8 */ {0, {308,180,324,254}, RADIO, N_("HPGL/2")},
17717  /*  9 */ {0, {332,20,348,187}, RADIO, N_("HPGL/2 plot fills page")},
17718  /* 10 */ {0, {356,20,372,177}, RADIO, N_("HPGL/2 plot fixed at:")},
17719  /* 11 */ {0, {356,180,372,240}, EDITTEXT, x_("")},
17720  /* 12 */ {0, {356,244,372,406}, MESSAGE, N_("internal units per pixel")},
17721  /* 13 */ {0, {260,20,276,172}, CHECK, N_("Synchronize to file:")},
17722  /* 14 */ {0, {260,172,292,464}, MESSAGE, x_("")},
17723  /* 15 */ {0, {236,20,252,108}, MESSAGE, N_("EPS Scale:")},
17724  /* 16 */ {0, {236,124,252,164}, EDITTEXT, x_("2")},
17725  /* 17 */ {0, {212,8,228,80}, MESSAGE, N_("For cell:")},
17726  /* 18 */ {0, {212,80,228,464}, MESSAGE, x_("")},
17727  /* 19 */ {0, {300,8,301,464}, DIVIDELINE, x_("")},
17728  /* 20 */ {0, {108,8,124,96}, MESSAGE, N_("PostScript:")},
17729  /* 21 */ {0, {108,312,124,464}, POPUP, x_("")},
17730  /* 22 */ {0, {100,8,101,464}, DIVIDELINE, x_("")},
17731  /* 23 */ {0, {308,8,324,98}, MESSAGE, N_("HPGL Level:")},
17732  /* 24 */ {0, {132,20,148,90}, RADIO, N_("Printer")},
17733  /* 25 */ {0, {132,100,148,170}, RADIO, N_("Plotter")},
17734  /* 26 */ {0, {156,20,172,100}, MESSAGE, N_("Width (in):")},
17735  /* 27 */ {0, {156,104,172,144}, EDITTEXT, x_("2")},
17736  /* 28 */ {0, {56,228,72,384}, POPUP, x_("")},
17737  /* 29 */ {0, {32,228,48,384}, MESSAGE, N_("Default printer:")},
17738  /* 30 */ {0, {156,172,172,260}, MESSAGE, N_("Height (in):")},
17739  /* 31 */ {0, {156,264,172,304}, EDITTEXT, x_("2")},
17740  /* 32 */ {0, {180,20,196,256}, POPUP, x_("")},
17741  /* 33 */ {0, {156,332,172,420}, MESSAGE, N_("Margin (in):")},
17742  /* 34 */ {0, {156,424,172,464}, EDITTEXT, x_("2")},
17743  /* 35 */ {0, {80,8,96,280}, MESSAGE, N_("Print and Copy resolution factor:")},
17744  /* 36 */ {0, {56,8,72,204}, RADIO, N_("Plot only Displayed Window")},
17745  /* 37 */ {0, {80,284,96,338}, EDITTEXT, x_("")}
17746 };
17747 static DIALOG us_printingoptdialog = {{50,75,431,549}, N_("Printing Options"), 0, 37, us_printingoptdialogitems, 0, 0};
17748 
17749 /* special items for the "print options" dialog: */
17750 #define DPRO_SHOWHIGHLIGHT    3		/* focus on highlighted (radio) */
17751 #define DPRO_SHOWALL          4		/* plot entire cell (radio) */
17752 #define DPRO_EPS              5		/* encapsulated postscript (check) */
17753 #define DPRO_PRINTDATE        6		/* date in corner (check) */
17754 #define DPRO_HPGL             7		/* HPGL (radio) */
17755 #define DPRO_HPGL2            8		/* HPGL/2 (radio) */
17756 #define DPRO_HPGL2FILLPAGE    9		/* HPGL/2 plot fills page (radio) */
17757 #define DPRO_HPGL2FIXSCALE   10		/* HPGL/2 plot fixed at (radio) */
17758 #define DPRO_HPGL2SCALE      11		/* HPGL/2 plot scale (edit text) */
17759 #define DPRO_HPGL2FIXSCALE_L 12		/* HPGL/2 plot fixed at (label) (stat text) */
17760 #define DPRO_SYNCHRONIZE     13		/* synchronize to file (check) */
17761 #define DPRO_SYNCHFILE       14		/* file to synchronize (stat text) */
17762 #define DPRO_EPSSCALE_L      15		/* EPS scale label (stat text) */
17763 #define DPRO_EPSSCALE        16		/* EPS scale (edit text) */
17764 #define DPRO_CELL_L          17		/* Cell label (stat text) */
17765 #define DPRO_CELL            18		/* Cell (stat text) */
17766 #define DPRO_PSSTYLE         21		/* PostScript style (popup) */
17767 #define DPRO_PRINTER         24		/* Printer (radio) */
17768 #define DPRO_PLOTTER         25		/* Plotter (radio) */
17769 #define DPRO_PRINTWID_L      26		/* Printer width label (stat text) */
17770 #define DPRO_PRINTWID        27		/* Printer width (edit text) */
17771 #define DPRO_PRINTERS        28		/* printer list (popup) */
17772 #define DPRO_PRINTHEI_L      30		/* Printer height label (stat text) */
17773 #define DPRO_PRINTHEI        31		/* Printer height (edit text) */
17774 #define DPRO_ROTATE          32		/* Rotate output (popup) */
17775 #define DPRO_PRINTMARGIN     34		/* Print margin (edit text) */
17776 #define DPRO_EXTRARES_L      35		/* label for extra resolution (stat text) */
17777 #define DPRO_SHOWWINDOW      36		/* plot displayed window (radio) */
17778 #define DPRO_EXTRARES        37		/* extra resolution when printing/copying (edit text) */
17779 
us_plotoptionsdlog(void)17780 INTBIG us_plotoptionsdlog(void)
17781 {
17782 	REGISTER INTBIG itemHit, scale, i, *curstate, wid, hei, margin, printercount,
17783 		oldplease, epsscale, resfactor;
17784 	INTBIG oldstate[NUMIOSTATEBITWORDS];
17785 	REGISTER VARIABLE *var;
17786 	REGISTER NODEPROTO *np;
17787 	REGISTER CHAR *pt;
17788 	CHAR buf[50], *subparams[3], *newlang[3], **printerlist, *defprinter;
17789 	static CHAR *postscripttype[4] = {N_("Black&White"), N_("Color"), N_("Color Stippled"), N_("Color Merged")};
17790 	static CHAR *rotatetype[3] = {N_("No Rotation"), N_("Rotate plot 90 degrees"),
17791 		N_("Auto-rotate plot to fit")};
17792 	REGISTER void *infstr;
17793 	REGISTER void *dia;
17794 
17795 	curstate = io_getstatebits();
17796 	for(i=0; i<NUMIOSTATEBITWORDS; i++) oldstate[i] = curstate[i];
17797 
17798 	/* display the print options dialog box */
17799 	dia = DiaInitDialog(&us_printingoptdialog);
17800 	if (dia == 0) return(0);
17801 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(postscripttype[i]);
17802 	DiaSetPopup(dia, DPRO_PSSTYLE, 4, newlang);
17803 	for(i=0; i<3; i++) newlang[i] = TRANSLATE(rotatetype[i]);
17804 	DiaSetPopup(dia, DPRO_ROTATE, 3, newlang);
17805 
17806 	/* show printers and default */
17807 	printerlist = eprinterlist();
17808 	for(printercount=0; printerlist[printercount] != 0; printercount++) ;
17809 	if (printercount == 0)
17810 	{
17811 		newlang[0] = _("<<Cannot set>>");
17812 		DiaSetPopup(dia, DPRO_PRINTERS, 1, newlang);
17813 	} else
17814 	{
17815 		DiaSetPopup(dia, DPRO_PRINTERS, printercount, printerlist);
17816 		defprinter = 0;
17817 		var = getval((INTBIG)io_tool, VTOOL, VSTRING, x_("IO_default_printer"));
17818 		if (var != NOVARIABLE) defprinter = (CHAR *)var->addr; else
17819 		{
17820 			CHAR *printer = egetenv(x_("PRINTER"));
17821 			if (printer != 0 && *printer != 0) defprinter = printer;
17822 		}
17823 		if (defprinter != 0)
17824 		{
17825 			for(i=0; i<printercount; i++)
17826 				if (namesame(defprinter, printerlist[i]) == 0) break;
17827 			if (i < printercount) DiaSetPopupEntry(dia, DPRO_PRINTERS, i);
17828 		}
17829 	}
17830 
17831 	/* show state */
17832 	switch (curstate[0]&(PSCOLOR1|PSCOLOR2))
17833 	{
17834 		case 0:                 DiaSetPopupEntry(dia, DPRO_PSSTYLE, 0);   break;
17835 		case PSCOLOR1:          DiaSetPopupEntry(dia, DPRO_PSSTYLE, 1);   break;
17836 		case PSCOLOR1|PSCOLOR2: DiaSetPopupEntry(dia, DPRO_PSSTYLE, 2);   break;
17837 		case PSCOLOR2:          DiaSetPopupEntry(dia, DPRO_PSSTYLE, 3);   break;
17838 	}
17839 	if ((curstate[0]&PLOTDATES) != 0) DiaSetControl(dia, DPRO_PRINTDATE, 1);
17840 	if ((curstate[0]&PLOTFOCUS) == 0) DiaSetControl(dia, DPRO_SHOWALL, 1); else
17841 	{
17842 		if ((curstate[0]&PLOTFOCUSDPY) != 0) DiaSetControl(dia, DPRO_SHOWWINDOW, 1); else
17843 			DiaSetControl(dia, DPRO_SHOWHIGHLIGHT, 1);
17844 	}
17845 	if ((curstate[0]&EPSPSCRIPT) != 0) DiaSetControl(dia, DPRO_EPS, 1);
17846 	if ((curstate[1]&PSAUTOROTATE) != 0) DiaSetPopupEntry(dia, DPRO_ROTATE, 2); else
17847 		if ((curstate[0]&PSROTATE) != 0) DiaSetPopupEntry(dia, DPRO_ROTATE, 1);
17848 	if ((curstate[0]&PSPLOTTER) != 0)
17849 	{
17850 		DiaSetControl(dia, DPRO_PLOTTER, 1);
17851 		DiaDimItem(dia, DPRO_PRINTHEI_L);
17852 		DiaDimItem(dia, DPRO_PRINTHEI);
17853 	} else
17854 	{
17855 		DiaSetControl(dia, DPRO_PRINTER, 1);
17856 		DiaUnDimItem(dia, DPRO_PRINTHEI_L);
17857 		DiaUnDimItem(dia, DPRO_PRINTHEI);
17858 	}
17859 
17860 	/* show PostScript page sizes */
17861 	var = getval((INTBIG)io_tool, VTOOL, VFRACT, x_("IO_postscript_width"));
17862 	if (var == NOVARIABLE) wid = muldiv(DEFAULTPSWIDTH, WHOLE, 75); else
17863 		wid = var->addr;
17864 	DiaSetText(dia, DPRO_PRINTWID, frtoa(wid));
17865 	var = getval((INTBIG)io_tool, VTOOL, VFRACT, x_("IO_postscript_height"));
17866 	if (var == NOVARIABLE) hei = muldiv(DEFAULTPSHEIGHT, WHOLE, 75); else
17867 		hei = var->addr;
17868 	DiaSetText(dia, DPRO_PRINTHEI, frtoa(hei));
17869 	var = getval((INTBIG)io_tool, VTOOL, VFRACT, x_("IO_postscript_margin"));
17870 	if (var == NOVARIABLE) margin = muldiv(DEFAULTPSMARGIN, WHOLE, 75); else
17871 		margin = var->addr;
17872 	DiaSetText(dia, DPRO_PRINTMARGIN, frtoa(margin));
17873 
17874 	/* show printer resolution scale factor */
17875 	var = getval((INTBIG)io_tool, VTOOL, VINTEGER, x_("IO_print_resolution_scale"));
17876 	if (var == NOVARIABLE) resfactor = 1; else
17877 		resfactor = var->addr;
17878 	esnprintf(buf, 50, x_("%ld"), resfactor);
17879 	DiaSetText(dia, DPRO_EXTRARES, buf);
17880 #ifndef WIN32
17881 	DiaDimItem(dia, DPRO_EXTRARES_L);
17882 	DiaDimItem(dia, DPRO_EXTRARES);
17883 #endif
17884 
17885 	np = el_curlib->curnodeproto;
17886 	DiaDimItem(dia, DPRO_EPSSCALE_L);
17887 	DiaDimItem(dia, DPRO_EPSSCALE);
17888 	epsscale = 1;
17889 	if (np == NONODEPROTO)
17890 	{
17891 		DiaDimItem(dia, DPRO_SYNCHRONIZE);
17892 		DiaDimItem(dia, DPRO_CELL_L);
17893 	} else
17894 	{
17895 		DiaSetText(dia, DPRO_CELL, describenodeproto(np));
17896 		DiaUnDimItem(dia, DPRO_CELL_L);
17897 		if ((curstate[0]&EPSPSCRIPT) != 0)
17898 		{
17899 			DiaUnDimItem(dia, DPRO_EPSSCALE_L);
17900 			DiaUnDimItem(dia, DPRO_EPSSCALE);
17901 			var = getvalkey((INTBIG)np, VNODEPROTO, VFRACT, io_postscriptepsscalekey);
17902 			if (var != NOVARIABLE && var->addr != 0)
17903 			{
17904 				epsscale = var->addr;
17905 			}
17906 			DiaSetText(dia, DPRO_EPSSCALE, frtoa(epsscale));
17907 		}
17908 		DiaUnDimItem(dia, DPRO_SYNCHRONIZE);
17909 		var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, io_postscriptfilenamekey);
17910 		if (var != NOVARIABLE)
17911 		{
17912 			DiaSetControl(dia, DPRO_SYNCHRONIZE, 1);
17913 			DiaSetText(dia, DPRO_SYNCHFILE, (CHAR *)var->addr);
17914 		}
17915 	}
17916 	if ((curstate[0]&HPGL2) != 0)
17917 	{
17918 		DiaSetControl(dia, DPRO_HPGL2, 1);
17919 		DiaUnDimItem(dia, DPRO_HPGL2FILLPAGE);
17920 		DiaUnDimItem(dia, DPRO_HPGL2FIXSCALE);
17921 		DiaUnDimItem(dia, DPRO_HPGL2FIXSCALE_L);
17922 		DiaEditControl(dia, DPRO_HPGL2SCALE);
17923 		var = getval((INTBIG)io_tool, VTOOL, VINTEGER, x_("IO_hpgl2_scale"));
17924 		if (var == NOVARIABLE)
17925 		{
17926 			DiaSetControl(dia, DPRO_HPGL2FILLPAGE, 1);
17927 			DiaSetText(dia, DPRO_HPGL2SCALE, x_("20"));
17928 		} else
17929 		{
17930 			DiaSetControl(dia, DPRO_HPGL2FIXSCALE, 1);
17931 			(void)esnprintf(buf, 50, x_("%ld"), var->addr);
17932 			DiaSetText(dia, DPRO_HPGL2SCALE, buf);
17933 		}
17934 	} else
17935 	{
17936 		DiaSetControl(dia, DPRO_HPGL, 1);
17937 		DiaSetControl(dia, DPRO_HPGL2FILLPAGE, 1);
17938 		DiaSetText(dia, DPRO_HPGL2SCALE, x_("20"));
17939 		DiaDimItem(dia, DPRO_HPGL2FILLPAGE);
17940 		DiaDimItem(dia, DPRO_HPGL2FIXSCALE);
17941 		DiaDimItem(dia, DPRO_HPGL2FIXSCALE_L);
17942 		DiaNoEditControl(dia, DPRO_HPGL2SCALE);
17943 	}
17944 
17945 	/* loop until done */
17946 	for(;;)
17947 	{
17948 		itemHit = DiaNextHit(dia);
17949 		if (itemHit == CANCEL || itemHit == OK) break;
17950 		if (itemHit == DPRO_EPS || itemHit == DPRO_PRINTDATE ||
17951 			itemHit == DPRO_SYNCHRONIZE)
17952 		{
17953 			i = 1 - DiaGetControl(dia, itemHit);
17954 			DiaSetControl(dia, itemHit, i);
17955 			if (itemHit == DPRO_EPS)
17956 			{
17957 				if (i == 0)
17958 				{
17959 					DiaDimItem(dia, DPRO_EPSSCALE_L);
17960 					DiaDimItem(dia, DPRO_EPSSCALE);
17961 				} else
17962 				{
17963 					DiaUnDimItem(dia, DPRO_EPSSCALE_L);
17964 					DiaUnDimItem(dia, DPRO_EPSSCALE);
17965 				}
17966 			}
17967 			if (itemHit == DPRO_SYNCHRONIZE)
17968 			{
17969 				if (i != 0)
17970 				{
17971 					/* select a file name to synchronize with this cell */
17972 					oldplease = el_pleasestop;
17973 					infstr = initinfstr();
17974 					addstringtoinfstr(infstr, x_("ps/"));
17975 					addstringtoinfstr(infstr, _("PostScript File: "));
17976 					i = ttygetparam(returninfstr(infstr), &us_colorwritep, 1, subparams);
17977 					el_pleasestop = oldplease;
17978 					if (i != 0 && subparams[0][0] != 0)
17979 					{
17980 						DiaUnDimItem(dia, DPRO_SYNCHFILE);
17981 						DiaSetText(dia, DPRO_SYNCHFILE, subparams[0]);
17982 					} else
17983 					{
17984 						DiaSetControl(dia, DPRO_SYNCHRONIZE, 0);
17985 					}
17986 				} else
17987 				{
17988 					DiaDimItem(dia, DPRO_SYNCHFILE);
17989 				}
17990 			}
17991 			continue;
17992 		}
17993 		if (itemHit == DPRO_SHOWHIGHLIGHT || itemHit == DPRO_SHOWALL ||
17994 			itemHit == DPRO_SHOWWINDOW)
17995 		{
17996 			DiaSetControl(dia, DPRO_SHOWHIGHLIGHT, 0);
17997 			DiaSetControl(dia, DPRO_SHOWALL, 0);
17998 			DiaSetControl(dia, DPRO_SHOWWINDOW, 0);
17999 			DiaSetControl(dia, itemHit, 1);
18000 			continue;
18001 		}
18002 		if (itemHit == DPRO_HPGL)
18003 		{
18004 			DiaSetControl(dia, DPRO_HPGL, 1);
18005 			DiaSetControl(dia, DPRO_HPGL2, 0);
18006 			DiaDimItem(dia, DPRO_HPGL2FILLPAGE);
18007 			DiaDimItem(dia, DPRO_HPGL2FIXSCALE);
18008 			DiaDimItem(dia, DPRO_HPGL2FIXSCALE_L);
18009 			DiaNoEditControl(dia, DPRO_HPGL2SCALE);
18010 			continue;
18011 		}
18012 		if (itemHit == DPRO_HPGL2)
18013 		{
18014 			DiaSetControl(dia, DPRO_HPGL, 0);
18015 			DiaSetControl(dia, DPRO_HPGL2, 1);
18016 			DiaUnDimItem(dia, DPRO_HPGL2FILLPAGE);
18017 			DiaUnDimItem(dia, DPRO_HPGL2FIXSCALE);
18018 			DiaUnDimItem(dia, DPRO_HPGL2FIXSCALE_L);
18019 			DiaEditControl(dia, DPRO_HPGL2SCALE);
18020 			continue;
18021 		}
18022 		if (itemHit == DPRO_HPGL2FILLPAGE || itemHit == DPRO_HPGL2FIXSCALE)
18023 		{
18024 			DiaSetControl(dia, DPRO_HPGL2FILLPAGE, 0);
18025 			DiaSetControl(dia, DPRO_HPGL2FIXSCALE, 0);
18026 			DiaSetControl(dia, itemHit, 1);
18027 			continue;
18028 		}
18029 		if (itemHit == DPRO_PRINTER || itemHit == DPRO_PLOTTER)
18030 		{
18031 			DiaSetControl(dia, DPRO_PRINTER, 0);
18032 			DiaSetControl(dia, DPRO_PLOTTER, 0);
18033 			DiaSetControl(dia, itemHit, 1);
18034 			if (itemHit == DPRO_PLOTTER)
18035 			{
18036 				DiaDimItem(dia, DPRO_PRINTHEI_L);
18037 				DiaDimItem(dia, DPRO_PRINTHEI);
18038 			} else
18039 			{
18040 				DiaUnDimItem(dia, DPRO_PRINTHEI_L);
18041 				DiaUnDimItem(dia, DPRO_PRINTHEI);
18042 			}
18043 			continue;
18044 		}
18045 	}
18046 
18047 	if (itemHit != CANCEL)
18048 	{
18049 		i = DiaGetPopupEntry(dia, DPRO_PRINTERS);
18050 		var = getval((INTBIG)io_tool, VTOOL, VSTRING, x_("IO_default_printer"));
18051 		if (i < printercount)
18052 		{
18053 			if (var == NOVARIABLE || estrcmp(printerlist[i], (CHAR *)var->addr) != 0)
18054 				(void)setval((INTBIG)io_tool, VTOOL, x_("IO_default_printer"),
18055 					(INTBIG)printerlist[i], VSTRING);
18056 		}
18057 
18058 		if (DiaGetControl(dia, DPRO_SHOWHIGHLIGHT) != 0)
18059 			curstate[0] = (curstate[0] & ~PLOTFOCUSDPY) | PLOTFOCUS; else
18060 		{
18061 			if (DiaGetControl(dia, DPRO_SHOWALL) != 0) curstate[0] &= ~(PLOTFOCUS|PLOTFOCUSDPY); else
18062 				curstate[0] |= PLOTFOCUSDPY | PLOTFOCUS;
18063 		}
18064 		if (DiaGetControl(dia, DPRO_EPS) != 0) curstate[0] |= EPSPSCRIPT; else
18065 			curstate[0] &= ~EPSPSCRIPT;
18066 		switch (DiaGetPopupEntry(dia, DPRO_ROTATE))
18067 		{
18068 			case 0: curstate[0] &= ~PSROTATE;   curstate[1] &= ~PSAUTOROTATE;   break;
18069 			case 1: curstate[0] |= PSROTATE;    curstate[1] &= ~PSAUTOROTATE;   break;
18070 			case 2: curstate[0] &= ~PSROTATE;   curstate[1] |= PSAUTOROTATE;    break;
18071 		}
18072 		if (DiaGetControl(dia, DPRO_PRINTDATE) != 0) curstate[0] |= PLOTDATES; else
18073 			curstate[0] &= ~PLOTDATES;
18074 		if (DiaGetControl(dia, DPRO_HPGL2) != 0) curstate[0] |= HPGL2; else
18075 			curstate[0] &= ~HPGL2;
18076 		switch (DiaGetPopupEntry(dia, DPRO_PSSTYLE))
18077 		{
18078 			case 0: curstate[0] &= ~(PSCOLOR1|PSCOLOR2);                  break;
18079 			case 1: curstate[0] = (curstate[0] & ~PSCOLOR2) | PSCOLOR1;   break;
18080 			case 2: curstate[0] |= PSCOLOR1 | PSCOLOR2;                   break;
18081 			case 3: curstate[0] = (curstate[0] & ~PSCOLOR1) | PSCOLOR2;   break;
18082 		}
18083 
18084 		/* set PostScript page sizes */
18085 		if (DiaGetControl(dia, DPRO_PRINTER) == 0) curstate[0] |= PSPLOTTER; else
18086 		{
18087 			/* printed */
18088 			curstate[0] &= ~PSPLOTTER;
18089 			i = atofr(DiaGetText(dia, DPRO_PRINTHEI));
18090 			if (i != hei)
18091 				(void)setval((INTBIG)io_tool, VTOOL, x_("IO_postscript_height"), i, VFRACT);
18092 		}
18093 		i = atofr(DiaGetText(dia, DPRO_PRINTWID));
18094 		if (i != wid)
18095 			(void)setval((INTBIG)io_tool, VTOOL, x_("IO_postscript_width"), i, VFRACT);
18096 		i = atofr(DiaGetText(dia, DPRO_PRINTMARGIN));
18097 		if (i != margin)
18098 			(void)setval((INTBIG)io_tool, VTOOL, x_("IO_postscript_margin"), i, VFRACT);
18099 
18100 		/* set printer resolution scale factor */
18101 		i = eatoi(DiaGetText(dia, DPRO_EXTRARES));
18102 		if (i != resfactor)
18103 			(void)setval((INTBIG)io_tool, VTOOL, x_("IO_print_resolution_scale"), i, VINTEGER);
18104 
18105 		if (np != NONODEPROTO)
18106 		{
18107 			var = getvalkey((INTBIG)np, VNODEPROTO, VSTRING, io_postscriptfilenamekey);
18108 			if (DiaGetControl(dia, DPRO_SYNCHRONIZE) != 0)
18109 			{
18110 				/* add a synchronization file */
18111 				pt = DiaGetText(dia, DPRO_SYNCHFILE);
18112 				if (var == NOVARIABLE || estrcmp(pt, (CHAR *)var->addr) != 0)
18113 					(void)setvalkey((INTBIG)np, VNODEPROTO, io_postscriptfilenamekey,
18114 						(INTBIG)pt, VSTRING);
18115 			} else
18116 			{
18117 				/* remove a synchronization file */
18118 				if (var != NOVARIABLE)
18119 					(void)delvalkey((INTBIG)np, VNODEPROTO, io_postscriptfilenamekey);
18120 			}
18121 			if (DiaGetControl(dia, DPRO_EPS) != 0)
18122 			{
18123 				i = atofr(DiaGetText(dia, DPRO_EPSSCALE));
18124 				if (i != epsscale)
18125 					(void)setvalkey((INTBIG)np, VNODEPROTO, io_postscriptepsscalekey,
18126 						i, VFRACT);
18127 			}
18128 		}
18129 		if ((curstate[0]&HPGL2) != 0)
18130 		{
18131 			var = getval((INTBIG)io_tool, VTOOL, VINTEGER, x_("IO_hpgl2_scale"));
18132 			if (DiaGetControl(dia, DPRO_HPGL2FILLPAGE) != 0)
18133 			{
18134 				if (var != NOVARIABLE)
18135 					(void)delval((INTBIG)io_tool, VTOOL, x_("IO_hpgl2_scale"));
18136 			} else
18137 			{
18138 				scale = myatoi(DiaGetText(dia, DPRO_HPGL2SCALE));
18139 				if (scale <= 0) scale = 1;
18140 				if (var == NOVARIABLE || scale != var->addr)
18141 					(void)setval((INTBIG)io_tool, VTOOL, x_("IO_hpgl2_scale"), scale, VINTEGER);
18142 			}
18143 		}
18144 
18145 		for(i=0; i<NUMIOSTATEBITWORDS; i++) if (curstate[i] != oldstate[i]) break;
18146 		if (i < NUMIOSTATEBITWORDS) io_setstatebits(curstate);
18147 	}
18148 	DiaDoneDialog(dia);
18149 	return(0);
18150 }
18151 
18152 /****************************** PURE LAYER NODE DIALOG ******************************/
18153 
18154 /* Edit: Pure Layer Node */
18155 static DIALOGITEM us_purelayerdialogitems[] =
18156 {
18157  /*  1 */ {0, {204,116,228,196}, BUTTON, N_("OK")},
18158  /*  2 */ {0, {204,12,228,92}, BUTTON, N_("Cancel")},
18159  /*  3 */ {0, {28,8,196,200}, SCROLL, x_("")},
18160  /*  4 */ {0, {4,12,20,100}, MESSAGE, N_("Technology:")},
18161  /*  5 */ {0, {4,100,20,200}, MESSAGE, x_("")}
18162 };
18163 static DIALOG us_purelayerdialog = {{75,75,312,284}, N_("Make Pure Layer Node"), 0, 5, us_purelayerdialogitems, 0, 0};
18164 
18165 /* special items for the "pure layer node" dialog: */
18166 #define DPLN_NODELIST     3		/* list of nodes (scroll) */
18167 #define DPLN_TECHNOLOGY   5		/* technology (stat text) */
18168 
us_purelayernodedlog(CHAR * paramstart[])18169 INTBIG us_purelayernodedlog(CHAR *paramstart[])
18170 {
18171 	REGISTER INTBIG itemHit, fun;
18172 	REGISTER INTBIG ret;
18173 	REGISTER NODEPROTO *np;
18174 	REGISTER void *dia;
18175 
18176 	if (us_needcell() == NONODEPROTO) return(0);
18177 
18178 	/* see if there are any pure layer nodes */
18179 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
18180 	{
18181 		fun = (np->userbits&NFUNCTION) >> NFUNCTIONSH;
18182 		if (fun == NPNODE) break;
18183 	}
18184 	if (np == NONODEPROTO)
18185 	{
18186 		ttyputerr(_("This technology has no pure-layer nodes"));
18187 		return(0);
18188 	}
18189 
18190 	/* display the dialog box */
18191 	dia = DiaInitDialog(&us_purelayerdialog);
18192 	if (dia == 0) return(0);
18193 	DiaInitTextDialog(dia, DPLN_NODELIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
18194 		SCSELMOUSE|SCDOUBLEQUIT);
18195 	for(np = el_curtech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
18196 	{
18197 		fun = (np->userbits&NFUNCTION) >> NFUNCTIONSH;
18198 		if (fun != NPNODE) continue;
18199 		DiaStuffLine(dia, DPLN_NODELIST, np->protoname);
18200 	}
18201 	DiaSelectLine(dia, DPLN_NODELIST, 0);
18202 	DiaSetText(dia, DPLN_TECHNOLOGY, el_curtech->techname);
18203 	/* loop until done */
18204 	for(;;)
18205 	{
18206 		itemHit = DiaNextHit(dia);
18207 		if (itemHit == OK || itemHit == CANCEL) break;
18208 	}
18209 	ret = 0;
18210 	if (itemHit == OK)
18211 	{
18212 		ret = 1;
18213 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
18214 		allocstring(&us_returneddialogstring,
18215 			DiaGetScrollLine(dia, DPLN_NODELIST, DiaGetCurLine(dia, DPLN_NODELIST)), us_tool->cluster);
18216 		paramstart[0] = us_returneddialogstring;
18217 	}
18218 	DiaDoneDialog(dia);
18219 	return(ret);
18220 }
18221 
18222 /****************************** QUICK KEY OPTIONS DIALOG ******************************/
18223 
18224 /* Quick Keys */
18225 static DIALOGITEM us_quickkeydialogitems[] =
18226 {
18227  /*  1 */ {0, {520,320,544,384}, BUTTON, N_("OK")},
18228  /*  2 */ {0, {520,12,544,76}, BUTTON, N_("Cancel")},
18229  /*  3 */ {0, {24,4,168,168}, SCROLL, x_("")},
18230  /*  4 */ {0, {192,20,336,184}, SCROLL, x_("")},
18231  /*  5 */ {0, {4,4,20,68}, MESSAGE, N_("Menu:")},
18232  /*  6 */ {0, {172,20,188,136}, MESSAGE, N_("SubMenu/Item:")},
18233  /*  7 */ {0, {360,36,504,200}, SCROLL, x_("")},
18234  /*  8 */ {0, {340,36,356,140}, MESSAGE, N_("SubItem:")},
18235  /*  9 */ {0, {24,228,504,392}, SCROLL, x_("")},
18236  /* 10 */ {0, {4,228,20,328}, MESSAGE, N_("Quick Key:")},
18237  /* 11 */ {0, {256,192,280,220}, BUTTON, x_(">>")},
18238  /* 12 */ {0, {520,236,544,296}, BUTTON, N_("Remove")},
18239  /* 13 */ {0, {520,96,544,216}, BUTTON, N_("Factory Settings")}
18240 };
18241 static DIALOG us_quickkeydialog = {{75,75,634,478}, N_("Quick Key Options"), 0, 13, us_quickkeydialogitems, 0, 0};
18242 
18243 static void us_setlastquickkeys(void *dia);
18244 static void us_setmiddlequickkeys(void *dia);
18245 static void us_loadquickkeys(POPUPMENU *pm);
18246 static CHAR *us_makequickkey(INTBIG i);
18247 
18248 /* special items for the "Quick Keys" dialog: */
18249 #define DQKO_MENULIST       3		/* menu list (scroll) */
18250 #define DQKO_SUBLIST        4		/* submenu/item list (scroll) */
18251 #define DQKO_SUBSUBLIST     7		/* subitem list (scroll) */
18252 #define DQKO_KEYLIST        9		/* quick key list (scroll) */
18253 #define DQKO_ADDKEY        11		/* ">>" (button) */
18254 #define DQKO_REMOVEKEY     12		/* "<<" (button) */
18255 #define DQKO_FACTORYRESET  13		/* Factory settings (button) */
18256 
18257 #define MAXQUICKKEYS 300
18258 static INTSML         us_quickkeyskeys[MAXQUICKKEYS];
18259 static INTBIG         us_quickkeysspecial[MAXQUICKKEYS];
18260 static POPUPMENU     *us_quickkeysmenu[MAXQUICKKEYS];
18261 static INTBIG         us_quickkeysindex[MAXQUICKKEYS];
18262 static INTBIG         us_quickkeyscount;
18263 
us_quickkeydlog(void)18264 INTBIG us_quickkeydlog(void)
18265 {
18266 	INTBIG itemHit, i, j, k, which, whichmiddle, whichbottom, keychanged, special;
18267 	CHAR **quickkeylist;
18268 	INTSML key;
18269 	INTBIG quickkeycount;
18270 	REGISTER CHAR *menuname, *menucommand, *pt;
18271 	REGISTER POPUPMENU *pm;
18272 	REGISTER POPUPMENUITEM *mi;
18273 	REGISTER USERCOM *uc;
18274 	REGISTER void *dia;
18275 
18276 	/* display the window view dialog box */
18277 	dia = DiaInitDialog(&us_quickkeydialog);
18278 	if (dia == 0) return(0);
18279 	DiaInitTextDialog(dia, DQKO_MENULIST, DiaNullDlogList, DiaNullDlogItem,
18280 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
18281 	DiaInitTextDialog(dia, DQKO_SUBLIST, DiaNullDlogList, DiaNullDlogItem,
18282 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
18283 	DiaInitTextDialog(dia, DQKO_SUBSUBLIST, DiaNullDlogList, DiaNullDlogItem,
18284 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
18285 	DiaInitTextDialog(dia, DQKO_KEYLIST, DiaNullDlogList, DiaNullDlogItem,
18286 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
18287 
18288 	/* make a list of quick keys */
18289 	us_buildquickkeylist();
18290 	for(i=0; i<us_quickkeyscount; i++)
18291 		DiaStuffLine(dia, DQKO_KEYLIST, us_makequickkey(i));
18292 	DiaSelectLine(dia, DQKO_KEYLIST, 0);
18293 
18294 	/* load the list of menus */
18295 	for(i=0; i<us_pulldownmenucount; i++)
18296 		DiaStuffLine(dia, DQKO_MENULIST, us_removeampersand(us_pulldowns[i]->header));
18297 	DiaSelectLine(dia, DQKO_MENULIST, 0);
18298 	us_setmiddlequickkeys(dia);
18299 
18300 	/* loop until done */
18301 	keychanged = 0;
18302 	for(;;)
18303 	{
18304 		itemHit = DiaNextHit(dia);
18305 		if (itemHit == OK || itemHit == CANCEL) break;
18306 		if (itemHit == DQKO_MENULIST)
18307 		{
18308 			/* click in the top list (the pulldown menus) */
18309 			us_setmiddlequickkeys(dia);
18310 			continue;
18311 		}
18312 		if (itemHit == DQKO_SUBLIST)
18313 		{
18314 			/* click in the middle list (the submenus/items) */
18315 			us_setlastquickkeys(dia);
18316 			continue;
18317 		}
18318 		if (itemHit == DQKO_SUBSUBLIST)
18319 		{
18320 			/* click in the lower list (the subitems) */
18321 			which = DiaGetCurLine(dia, DQKO_MENULIST);
18322 			whichmiddle = DiaGetCurLine(dia, DQKO_SUBLIST);
18323 			whichbottom = DiaGetCurLine(dia, DQKO_SUBSUBLIST);
18324 			pm = us_pulldowns[which];
18325 			mi = &pm->list[whichmiddle];
18326 			uc = mi->response;
18327 			pm = uc->menu;
18328 			if (pm == NOPOPUPMENU) continue;
18329 			for(j=0; j<us_quickkeyscount; j++)
18330 				if (pm == us_quickkeysmenu[j] && whichbottom == us_quickkeysindex[j]) break;
18331 			if (j < us_quickkeyscount) DiaSelectLine(dia, DQKO_KEYLIST, j);
18332 			continue;
18333 		}
18334 		if (itemHit == DQKO_ADDKEY)
18335 		{
18336 			/* click in the ">>" button (add command to quick keys) */
18337 			which = DiaGetCurLine(dia, DQKO_MENULIST);
18338 			whichmiddle = DiaGetCurLine(dia, DQKO_SUBLIST);
18339 			whichbottom = DiaGetCurLine(dia, DQKO_SUBSUBLIST);
18340 			pm = us_pulldowns[which];
18341 			mi = &pm->list[whichmiddle];
18342 			uc = mi->response;
18343 			if (uc->menu != NOPOPUPMENU)
18344 			{
18345 				pm = uc->menu;
18346 				whichmiddle = whichbottom;
18347 			}
18348 			which = DiaGetCurLine(dia, DQKO_KEYLIST);
18349 			us_quickkeysmenu[which] = pm;
18350 			us_quickkeysindex[which] = whichmiddle;
18351 			DiaSetScrollLine(dia, DQKO_KEYLIST, which, us_makequickkey(which));
18352 			keychanged++;
18353 			continue;
18354 		}
18355 		if (itemHit == DQKO_REMOVEKEY)
18356 		{
18357 			/* click in the "<<" button (remove command from quick key) */
18358 			which = DiaGetCurLine(dia, DQKO_KEYLIST);
18359 			us_quickkeysmenu[which] = NOPOPUPMENU;
18360 			DiaSetScrollLine(dia, DQKO_KEYLIST, which, us_makequickkey(which));
18361 			keychanged++;
18362 			continue;
18363 		}
18364 		if (itemHit == DQKO_FACTORYRESET)
18365 		{
18366 			/* click in the "Factory Settings" button */
18367 			for(i=0; i<us_quickkeyscount; i++)
18368 				us_quickkeysmenu[i] = NOPOPUPMENU;
18369 			for(i=0; i<us_quickkeyfactcount; i++)
18370 			{
18371 				pt = us_quickkeyfactlist[i];
18372 				menuname = us_getboundkey(pt, &key, &special);
18373 				for(j=0; j<us_quickkeyscount; j++)
18374 				{
18375 					if (us_samekey(key, special, us_quickkeyskeys[j], us_quickkeysspecial[j]))
18376 						break;
18377 				}
18378 				if (j >= us_quickkeyscount) continue;
18379 				for(pt = menuname; *pt != 0 && *pt != '/'; pt++) ;
18380 				if (*pt == 0) continue;
18381 				*pt = 0;
18382 				pm = us_getpopupmenu(menuname);
18383 				*pt = '/';
18384 				menucommand = pt + 1;
18385 				for(k=0; k<pm->total; k++)
18386 				{
18387 					mi = &pm->list[k];
18388 					if (namesame(us_removeampersand(mi->attribute), menucommand) == 0) break;
18389 				}
18390 				if (k >= pm->total) continue;
18391 				us_quickkeysmenu[j] = pm;
18392 				us_quickkeysindex[j] = k;
18393 			}
18394 			DiaLoadTextDialog(dia, DQKO_KEYLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
18395 			for(i=0; i<us_quickkeyscount; i++)
18396 				DiaStuffLine(dia, DQKO_KEYLIST, us_makequickkey(i));
18397 			DiaSelectLine(dia, DQKO_KEYLIST, 0);
18398 			keychanged++;
18399 			continue;
18400 		}
18401 	}
18402 
18403 	DiaDoneDialog(dia);
18404 	if (itemHit == OK && keychanged != 0)
18405 	{
18406 		us_getquickkeylist(&quickkeycount, &quickkeylist);
18407 		(void)setvalkey((INTBIG)us_tool, VTOOL, us_quickkeyskey, (INTBIG)quickkeylist,
18408 			VSTRING|VISARRAY|(quickkeycount<<VLENGTHSH));
18409 		for(i=0; i<quickkeycount; i++)
18410 			efree((CHAR *)quickkeylist[i]);
18411 		efree((CHAR *)quickkeylist);
18412 	}
18413 	return(0);
18414 }
18415 
18416 /*
18417  * Helper routine for "us_quickkeydlog" to construct the string describing key "i".
18418  */
us_makequickkey(INTBIG i)18419 CHAR *us_makequickkey(INTBIG i)
18420 {
18421 	REGISTER POPUPMENUITEM *mi;
18422 	REGISTER void *infstr;
18423 
18424 	infstr = initinfstr();
18425 	addstringtoinfstr(infstr, us_describeboundkey(us_quickkeyskeys[i], us_quickkeysspecial[i], 1));
18426 	if (us_quickkeysmenu[i] != NOPOPUPMENU)
18427 	{
18428 		mi = &us_quickkeysmenu[i]->list[us_quickkeysindex[i]];
18429 		addstringtoinfstr(infstr, x_("   "));
18430 		addstringtoinfstr(infstr, us_removeampersand(mi->attribute));
18431 	}
18432 	return(returninfstr(infstr));
18433 }
18434 
18435 /*
18436  * Routine to scan all pulldown menus and build an internal list of quick keys.
18437  */
us_buildquickkeylist(void)18438 void us_buildquickkeylist(void)
18439 {
18440 	REGISTER INTBIG i, morebits;
18441 
18442 	us_quickkeyscount = 0;
18443 	for(i=0; i<26; i++)
18444 	{
18445 		us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18446 		us_quickkeyskeys[us_quickkeyscount] = (CHAR)('A' + i);
18447 		us_quickkeyscount++;
18448 	}
18449 	for(i=0; i<10; i++)
18450 	{
18451 		us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18452 		us_quickkeyskeys[us_quickkeyscount] = (CHAR)('0' + i);
18453 		us_quickkeyscount++;
18454 	}
18455 	for(i=0; i<26; i++)
18456 	{
18457 		us_quickkeysspecial[us_quickkeyscount] = 0;
18458 		us_quickkeyskeys[us_quickkeyscount] = (CHAR)('a' + i);
18459 		us_quickkeyscount++;
18460 	}
18461 	for(i=0; i<26; i++)
18462 	{
18463 		us_quickkeysspecial[us_quickkeyscount] = 0;
18464 		us_quickkeyskeys[us_quickkeyscount] = (CHAR)('A' + i);
18465 		us_quickkeyscount++;
18466 	}
18467 	for(i=0; i<10; i++)
18468 	{
18469 		us_quickkeysspecial[us_quickkeyscount] = 0;
18470 		us_quickkeyskeys[us_quickkeyscount] = (CHAR)('0' + i);
18471 		us_quickkeyscount++;
18472 	}
18473 	us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18474 	us_quickkeyskeys[us_quickkeyscount] = '.';
18475 	us_quickkeyscount++;
18476 	us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18477 	us_quickkeyskeys[us_quickkeyscount] = ',';
18478 	us_quickkeyscount++;
18479 	us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18480 	us_quickkeyskeys[us_quickkeyscount] = '+';
18481 	us_quickkeyscount++;
18482 	us_quickkeysspecial[us_quickkeyscount] = ACCELERATORDOWN;
18483 	us_quickkeyskeys[us_quickkeyscount] = '-';
18484 	us_quickkeyscount++;
18485 	for(i=0; i<12; i++)
18486 	{
18487 		us_quickkeysspecial[us_quickkeyscount] = 0;
18488 		us_quickkeysspecial[us_quickkeyscount] =
18489 			SPECIALKEYDOWN|((SPECIALKEYF1+i)<<SPECIALKEYSH);
18490 		us_quickkeyscount++;
18491 	}
18492 	for(i=0; i<4; i++)
18493 	{
18494 		morebits = 0;
18495 		if ((i&1) != 0) morebits |= SHIFTDOWN;
18496 		if ((i&2) != 0) morebits |= ACCELERATORDOWN;
18497 		us_quickkeyskeys[us_quickkeyscount] = 0;
18498 		us_quickkeysspecial[us_quickkeyscount] =
18499 			SPECIALKEYDOWN|((SPECIALKEYARROWL)<<SPECIALKEYSH)|morebits;
18500 		us_quickkeyscount++;
18501 		us_quickkeyskeys[us_quickkeyscount] = 0;
18502 		us_quickkeysspecial[us_quickkeyscount] =
18503 			SPECIALKEYDOWN|((SPECIALKEYARROWR)<<SPECIALKEYSH)|morebits;
18504 		us_quickkeyscount++;
18505 		us_quickkeyskeys[us_quickkeyscount] = 0;
18506 		us_quickkeysspecial[us_quickkeyscount] =
18507 			SPECIALKEYDOWN|((SPECIALKEYARROWU)<<SPECIALKEYSH)|morebits;
18508 		us_quickkeyscount++;
18509 		us_quickkeyskeys[us_quickkeyscount] = 0;
18510 		us_quickkeysspecial[us_quickkeyscount] =
18511 			SPECIALKEYDOWN|((SPECIALKEYARROWD)<<SPECIALKEYSH)|morebits;
18512 		us_quickkeyscount++;
18513 	}
18514 
18515 	for(i=0; i<us_quickkeyscount; i++) us_quickkeysmenu[i] = NOPOPUPMENU;
18516 	for(i=0; i<us_pulldownmenucount; i++)
18517 		us_loadquickkeys(us_pulldowns[i]);
18518 }
18519 
18520 /*
18521  * Routine to convert the internal list of quick keys to an array of bindings
18522  * in "quickkeylist" (that is "quickkeycount" long).
18523  */
us_getquickkeylist(INTBIG * quickkeycount,CHAR *** quickkeylist)18524 void us_getquickkeylist(INTBIG *quickkeycount, CHAR ***quickkeylist)
18525 {
18526 	REGISTER INTBIG count, i;
18527 	REGISTER CHAR **keylist;
18528 	REGISTER POPUPMENUITEM *mi;
18529 	REGISTER void *infstr;
18530 
18531 	count = 0;
18532 	for(i=0; i<us_quickkeyscount; i++)
18533 		if (us_quickkeysmenu[i] != NOPOPUPMENU) count++;
18534 	keylist = (CHAR **)emalloc(count * (sizeof (CHAR *)), us_tool->cluster);
18535 	if (keylist == 0)
18536 	{
18537 		*quickkeycount = 0;
18538 		return;
18539 	}
18540 	count = 0;
18541 	for(i=0; i<us_quickkeyscount; i++)
18542 	{
18543 		if (us_quickkeysmenu[i] == NOPOPUPMENU) continue;
18544 		infstr = initinfstr();
18545 		addstringtoinfstr(infstr, us_describeboundkey(us_quickkeyskeys[i], us_quickkeysspecial[i], 0));
18546 		addstringtoinfstr(infstr, us_quickkeysmenu[i]->name);
18547 		addtoinfstr(infstr, '/');
18548 		mi = &us_quickkeysmenu[i]->list[us_quickkeysindex[i]];
18549 		addstringtoinfstr(infstr, us_removeampersand(mi->attribute));
18550 		(void)allocstring(&keylist[count], returninfstr(infstr), us_tool->cluster);
18551 		count++;
18552 	}
18553 	*quickkeycount = count;
18554 	*quickkeylist = keylist;
18555 }
18556 
18557 /*
18558  * Helper routine for "us_quickkeydlog" to recursively examine menu "pm" and
18559  * load the quick keys tables.
18560  */
us_loadquickkeys(POPUPMENU * pm)18561 void us_loadquickkeys(POPUPMENU *pm)
18562 {
18563 	REGISTER INTBIG j, i;
18564 	INTSML key;
18565 	INTBIG special;
18566 	REGISTER POPUPMENUITEM *mi;
18567 	REGISTER USERCOM *uc;
18568 	REGISTER CHAR *pt;
18569 	CHAR menuline[200];
18570 
18571 	for(i=0; i<pm->total; i++)
18572 	{
18573 		mi = &pm->list[i];
18574 		uc = mi->response;
18575 		if (uc->menu != NOPOPUPMENU)
18576 		{
18577 			us_loadquickkeys(uc->menu);
18578 			continue;
18579 		}
18580 		if (uc->active < 0 && *mi->attribute == 0) continue;
18581 
18582 		estrcpy(menuline, mi->attribute);
18583 		j = estrlen(menuline) - 1;
18584 		if (menuline[j] == '<') menuline[j] = 0;
18585 		for(pt = menuline; *pt != 0; pt++)
18586 			if (*pt == '/' || *pt == '\\') break;
18587 		if (*pt == 0) continue;
18588 		(void)us_getboundkey(pt, &key, &special);
18589 		for(j=0; j<us_quickkeyscount; j++)
18590 		{
18591 			if (!us_samekey(key, special, us_quickkeyskeys[j], us_quickkeysspecial[j]))
18592 				continue;
18593 			us_quickkeysmenu[j] = pm;
18594 			us_quickkeysindex[j] = i;
18595 		}
18596 	}
18597 }
18598 
18599 /*
18600  * Helper routine for "us_quickkeydlog" to load the middle table (the
18601  * submenu/items) when the selected top table has changed.
18602  */
us_setmiddlequickkeys(void * dia)18603 void us_setmiddlequickkeys(void *dia)
18604 {
18605 	REGISTER INTBIG which, i;
18606 	REGISTER POPUPMENU *pm;
18607 	REGISTER POPUPMENUITEM *mi;
18608 	REGISTER USERCOM *uc;
18609 
18610 	DiaLoadTextDialog(dia, DQKO_SUBLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
18611 	which = DiaGetCurLine(dia, DQKO_MENULIST);
18612 	pm = us_pulldowns[which];
18613 	for(i=0; i<pm->total; i++)
18614 	{
18615 		mi = &pm->list[i];
18616 		uc = mi->response;
18617 		if (uc->active < 0 && *mi->attribute == 0)
18618 		{
18619 			DiaStuffLine(dia, DQKO_SUBLIST, x_("---"));
18620 			continue;
18621 		}
18622 		DiaStuffLine(dia, DQKO_SUBLIST, us_removeampersand(mi->attribute));
18623 	}
18624 	DiaSelectLine(dia, DQKO_SUBLIST, 0);
18625 	us_setlastquickkeys(dia);
18626 }
18627 
18628 /*
18629  * Helper routine for "us_quickkeydlog" to load the bottom table (the
18630  * subitems) when the selected middle table has changed.
18631  */
us_setlastquickkeys(void * dia)18632 void us_setlastquickkeys(void *dia)
18633 {
18634 	REGISTER INTBIG which, whichmiddle, i, j;
18635 	REGISTER POPUPMENU *pm;
18636 	REGISTER POPUPMENUITEM *mi;
18637 	REGISTER USERCOM *uc;
18638 
18639 	DiaLoadTextDialog(dia, DQKO_SUBSUBLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
18640 	which = DiaGetCurLine(dia, DQKO_MENULIST);
18641 	whichmiddle = DiaGetCurLine(dia, DQKO_SUBLIST);
18642 	pm = us_pulldowns[which];
18643 	mi = &pm->list[whichmiddle];
18644 	uc = mi->response;
18645 	if (uc->menu != NOPOPUPMENU)
18646 	{
18647 		pm = uc->menu;
18648 		for(i=0; i<pm->total; i++)
18649 		{
18650 			mi = &pm->list[i];
18651 			uc = mi->response;
18652 			if (uc->active < 0 && *mi->attribute == 0)
18653 			{
18654 				DiaStuffLine(dia, DQKO_SUBSUBLIST, x_("---"));
18655 				continue;
18656 			}
18657 			DiaStuffLine(dia, DQKO_SUBSUBLIST, us_removeampersand(mi->attribute));
18658 		}
18659 		DiaSelectLine(dia, DQKO_SUBSUBLIST, 0);
18660 		mi = &pm->list[0];
18661 		whichmiddle = 0;
18662 	}
18663 
18664 	for(j=0; j<us_quickkeyscount; j++)
18665 		if (pm == us_quickkeysmenu[j] && whichmiddle == us_quickkeysindex[j]) break;
18666 	if (j < us_quickkeyscount) DiaSelectLine(dia, DQKO_KEYLIST, j);
18667 }
18668 
18669 /****************************** QUIT DIALOG ******************************/
18670 
18671 /* Quit */
18672 static DIALOGITEM us_quitdialogitems[] =
18673 {
18674  /*  1 */ {0, {100,16,124,80}, BUTTON, N_("Yes")},
18675  /*  2 */ {0, {100,128,124,208}, BUTTON, N_("Cancel")},
18676  /*  3 */ {0, {136,16,160,80}, BUTTON, N_("No")},
18677  /*  4 */ {0, {8,16,92,208}, MESSAGE, x_("")},
18678  /*  5 */ {0, {136,128,160,208}, BUTTON, N_("No to All")}
18679 };
18680 static DIALOG us_quitdialog = {{50,75,219,293}, 0, 0, 5, us_quitdialogitems, 0, 0};
18681 
18682 /* special items for the "quit" command: */
18683 #define DQUT_YES      1		/* Yes (button) */
18684 #define DQUT_CANCEL   2		/* Cancel (button) */
18685 #define DQUT_NO       3		/* No (button) */
18686 #define DQUT_MESSAGE  4		/* Message (stat text) */
18687 #define DQUT_NOTOALL  5		/* No to All (button) */
18688 
18689 /*
18690  * Returns:
18691  *  0  cancel ("Cancel")
18692  *  1  do not save ("No")
18693  *  2  do not save any libraries ("No to all")
18694  *  3  save ("Yes")
18695  */
us_quitdlog(CHAR * prompt,INTBIG notoall)18696 INTBIG us_quitdlog(CHAR *prompt, INTBIG notoall)
18697 {
18698 	INTBIG itemHit, i, len, oldplease;
18699 	INTBIG retval;
18700 	REGISTER void *infstr;
18701 	REGISTER void *dia;
18702 
18703 	/* display the quit dialog box */
18704 	if (notoall == 0) us_quitdialog.items = 4; else
18705 		us_quitdialog.items = 5;
18706 	dia = DiaInitDialog(&us_quitdialog);
18707 	if (dia == 0) return(0);
18708 
18709 	/* load the message */
18710 	len = estrlen(prompt);
18711 	for(i=0; i<len; i++) if (estrncmp(&prompt[i], _(" has changed.  "), 15) == 0) break;
18712 	if (i >= len) DiaSetText(dia, DQUT_MESSAGE, prompt); else
18713 	{
18714 		infstr = initinfstr();
18715 		prompt[i+15] = 0;
18716 		addstringtoinfstr(infstr, prompt);
18717 		addstringtoinfstr(infstr, _("Save?"));
18718 		DiaSetText(dia, DQUT_MESSAGE, returninfstr(infstr));
18719 	}
18720 
18721 	/* loop until done */
18722 	oldplease = el_pleasestop;
18723 	for(;;)
18724 	{
18725 		itemHit = DiaNextHit(dia);
18726 		if (itemHit == OK || itemHit == CANCEL ||
18727 			itemHit == DQUT_NO || itemHit == DQUT_NOTOALL) break;
18728 	}
18729 	el_pleasestop = oldplease;
18730 
18731 	DiaDoneDialog(dia);
18732 	switch (itemHit)
18733 	{
18734 		case CANCEL:       retval = 0;   break;
18735 		case DQUT_NO:      retval = 1;   break;
18736 		case DQUT_NOTOALL: retval = 2;   break;
18737 		case OK:           retval = 3;   break;
18738 	}
18739 	return(retval);
18740 }
18741 
18742 /****************************** RENAME DIALOG ******************************/
18743 
18744 /* Rename */
18745 static DIALOGITEM us_rendialogitems[] =
18746 {
18747  /*  1 */ {0, {196,236,220,316}, BUTTON, N_("OK")},
18748  /*  2 */ {0, {116,236,140,316}, BUTTON, N_("Cancel")},
18749  /*  3 */ {0, {56,8,288,220}, SCROLL, x_("")},
18750  /*  4 */ {0, {292,8,308,88}, MESSAGE, N_("New name:")},
18751  /*  5 */ {0, {292,84,308,316}, EDITTEXT, x_("")},
18752  /*  6 */ {0, {8,8,24,316}, POPUP, x_("")},
18753  /*  7 */ {0, {32,84,48,316}, POPUP, x_("")},
18754  /*  8 */ {0, {32,8,48,84}, MESSAGE, N_("Library:")}
18755 };
18756 static DIALOG us_rendialog = {{75,75,392,401}, N_("Rename Object"), 0, 8, us_rendialogitems, 0, 0};
18757 
18758 /* special items for the "rename" dialog: */
18759 #define DREN_OLDNAMES    3		/* list of old names (scroll) */
18760 #define DREN_NEWNAME     5		/* new name (edit text) */
18761 #define DREN_OBJTYPE     6		/* object type (popup) */
18762 #define DREN_LIBRARY     7		/* library selection (popup) */
18763 #define DREN_LIBRARY_L   8		/* library label (stat text) */
18764 
18765 #define RENAMECATEGORIES  5
18766 
18767 static INTBIG      us_renametype;
18768 static LIBRARY    *us_renamelib;
18769 static LIBRARY    *us_renamecurlib;
18770 static TECHNOLOGY *us_renametech;
18771 static PORTPROTO  *us_renamediaport;
18772 static NODEPROTO  *us_renamenodeproto;
18773 static INTBIG      us_renamenetindex;
18774 static void       *us_renamenetsa;
18775 
18776 static BOOLEAN us_initrenamelist(CHAR **c);
18777 static CHAR   *us_renamelistitem(void);
18778 
us_renamedlog(INTBIG type)18779 INTBIG us_renamedlog(INTBIG type)
18780 {
18781 	REGISTER INTBIG itemHit, typeindex;
18782 	INTBIG count, i;
18783 	REGISTER BOOLEAN initcatagory;
18784 	CHAR *par[3], *newlang[7], **liblist;
18785 	REGISTER void *dia, *infstr;
18786 	static CHAR *renamename[RENAMECATEGORIES] = {N_("Libraries:"), N_("Technologies:"),
18787 		N_("Exports:"), N_("Cells:"), N_("Networks:")};
18788 	static INTBIG renametype[RENAMECATEGORIES] = {VLIBRARY, VTECHNOLOGY, VPORTPROTO, VNODEPROTO, VNETWORK};
18789 	static CHAR *renameletter[RENAMECATEGORIES] = {x_("l"), x_("t"), x_("r"), x_("p"), x_("n")};
18790 
18791 	/* display the rename dialog box */
18792 	dia = DiaInitDialog(&us_rendialog);
18793 	if (dia == 0) return(0);
18794 	us_renamenetsa = 0;
18795 	for(i=0; i<RENAMECATEGORIES; i++) newlang[i] = TRANSLATE(renamename[i]);
18796 	DiaSetPopup(dia, DREN_OBJTYPE, RENAMECATEGORIES, newlang);
18797 	for(typeindex=0; typeindex<RENAMECATEGORIES; typeindex++)
18798 	{
18799 		if (type == renametype[typeindex])
18800 		{
18801 			DiaSetPopupEntry(dia, DREN_OBJTYPE, typeindex);
18802 			break;
18803 		}
18804 	}
18805 	liblist = us_makelibrarylist(&count, el_curlib, &i);
18806 	DiaSetPopup(dia, DREN_LIBRARY, count, liblist);
18807 	if (i >= 0) DiaSetPopupEntry(dia, DREN_LIBRARY, i);
18808 	us_renamecurlib = el_curlib;
18809 
18810 	/* loop until done */
18811 	initcatagory = TRUE;
18812 	for(;;)
18813 	{
18814 		if (initcatagory)
18815 		{
18816 			initcatagory = FALSE;
18817 			typeindex = DiaGetPopupEntry(dia, DREN_OBJTYPE);
18818 			us_renametype = renametype[typeindex];
18819 			DiaInitTextDialog(dia, DREN_OLDNAMES, us_initrenamelist, us_renamelistitem,
18820 				DiaNullDlogDone, 0, SCSELMOUSE|SCREPORT);
18821 			if (us_renametype == VNODEPROTO)
18822 			{
18823 				DiaUnDimItem(dia, DREN_LIBRARY);
18824 				DiaUnDimItem(dia, DREN_LIBRARY_L);
18825 				(void)us_setscrolltocurrentcell(DREN_OLDNAMES, TRUE, TRUE, FALSE, TRUE, dia);
18826 			} else
18827 			{
18828 				DiaDimItem(dia, DREN_LIBRARY);
18829 				DiaDimItem(dia, DREN_LIBRARY_L);
18830 			}
18831 			i = DiaGetCurLine(dia, DREN_OLDNAMES);
18832 			if (i >= 0)
18833 				DiaSetText(dia, -DREN_NEWNAME, DiaGetScrollLine(dia, DREN_OLDNAMES, i));
18834 		}
18835 		itemHit = DiaNextHit(dia);
18836 		if (itemHit == CANCEL) break;
18837 		if (itemHit == OK)
18838 		{
18839 			i = DiaGetCurLine(dia, DREN_OLDNAMES);
18840 			if (i < 0) continue;
18841 			if (!DiaValidEntry(dia, DREN_NEWNAME)) continue;
18842 
18843 			/* do the rename */
18844 			par[2] = renameletter[typeindex];
18845 			i = DiaGetCurLine(dia, DREN_OLDNAMES);
18846 			infstr = initinfstr();
18847 			if (us_renametype == VNODEPROTO)
18848 				formatinfstr(infstr, x_("%s:"), us_renamecurlib->libname);
18849 			addstringtoinfstr(infstr, DiaGetScrollLine(dia, DREN_OLDNAMES, i));
18850 			allocstring(&par[0], returninfstr(infstr), el_tempcluster);
18851 			allocstring(&par[1], DiaGetText(dia, DREN_NEWNAME), el_tempcluster);
18852 			us_rename(3, par);
18853 			efree((CHAR *)par[0]);
18854 			efree((CHAR *)par[1]);
18855 			break;
18856 		}
18857 		if (itemHit == DREN_OLDNAMES)
18858 		{
18859 			i = DiaGetCurLine(dia, DREN_OLDNAMES);
18860 			if (i >= 0)
18861 				DiaSetText(dia, -DREN_NEWNAME, DiaGetScrollLine(dia, DREN_OLDNAMES, i));
18862 			continue;
18863 		}
18864 		if (itemHit == DREN_OBJTYPE)
18865 		{
18866 			initcatagory = TRUE;
18867 			continue;
18868 		}
18869 		if (itemHit == DREN_LIBRARY)
18870 		{
18871 			typeindex = DiaGetPopupEntry(dia, DREN_LIBRARY);
18872 			us_renamecurlib = getlibrary(liblist[typeindex]);
18873 			initcatagory = TRUE;
18874 			continue;
18875 		}
18876 	}
18877 	if (us_renamenetsa != 0) killstringarray(us_renamenetsa);
18878 	if (liblist != 0) efree((CHAR *)liblist);
18879 	DiaDoneDialog(dia);
18880 	return(0);
18881 }
18882 
us_initrenamelist(CHAR ** c)18883 BOOLEAN us_initrenamelist(CHAR **c)
18884 {
18885 	Q_UNUSED( c );
18886 	REGISTER NODEPROTO *np;
18887 	CHAR **strings;
18888 	REGISTER INTBIG i;
18889 	INTBIG count;
18890 	REGISTER CHAR *pt, save, *ptr;
18891 	REGISTER NETWORK *net;
18892 
18893 	us_renamelib = el_curlib;
18894 	us_renametech = el_technologies;
18895 	us_renamenodeproto = us_renamecurlib->firstnodeproto;
18896 	np = getcurcell();
18897 	if (np == NONODEPROTO)
18898 	{
18899 		us_renamediaport = NOPORTPROTO;
18900 		us_renamenetindex = 0;
18901 	} else
18902 	{
18903 		us_renamediaport = np->firstportproto;
18904 		us_renamenetindex = 0;
18905 		if (us_renametype == VNETWORK)
18906 		{
18907 			if (us_renamenetsa == 0)
18908 				us_renamenetsa = newstringarray(us_tool->cluster);
18909 			clearstrings(us_renamenetsa);
18910 			for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
18911 			{
18912 				for(i=0; i<net->namecount; i++)
18913 				{
18914 					pt = networkname(net, i);
18915 					for(ptr = pt; *ptr != 0; ptr++)
18916 						if (*ptr == '[') break;
18917 					save = *ptr;
18918 					*ptr = 0;
18919 					addtostringarray(us_renamenetsa, pt);
18920 					*ptr = save;
18921 				}
18922 			}
18923 			strings = getstringarray(us_renamenetsa, &count);
18924 			esort(strings, count, sizeof (CHAR *), sort_stringascending);
18925 		}
18926 	}
18927 	return(TRUE);
18928 }
18929 
us_renamelistitem(void)18930 CHAR *us_renamelistitem(void)
18931 {
18932 	REGISTER LIBRARY *lib;
18933 	REGISTER TECHNOLOGY *tech;
18934 	REGISTER NODEPROTO *np;
18935 	REGISTER PORTPROTO *pp;
18936 	REGISTER CHAR *pt;
18937 	CHAR **strings;
18938 	INTBIG count;
18939 
18940 	switch (us_renametype)
18941 	{
18942 		case VLIBRARY:
18943 			for(;;)
18944 			{
18945 				if (us_renamelib == NOLIBRARY) break;
18946 				lib = us_renamelib;
18947 				us_renamelib = us_renamelib->nextlibrary;
18948 				if ((lib->userbits&HIDDENLIBRARY) != 0) continue;
18949 				return(lib->libname);
18950 			}
18951 			break;
18952 		case VTECHNOLOGY:
18953 			if (us_renametech == NOTECHNOLOGY) break;
18954 			tech = us_renametech;
18955 			us_renametech = us_renametech->nexttechnology;
18956 			return(tech->techname);
18957 		case VPORTPROTO:
18958 			if (us_renamediaport == NOPORTPROTO) break;
18959 			pp = us_renamediaport;
18960 			us_renamediaport = us_renamediaport->nextportproto;
18961 			return(pp->protoname);
18962 		case VNODEPROTO:
18963 			if (us_renamenodeproto == NONODEPROTO) break;
18964 			np = us_renamenodeproto;
18965 			us_renamenodeproto = us_renamenodeproto->nextnodeproto;
18966 			return(np->protoname);
18967 		case VNETWORK:
18968 			for(;;)
18969 			{
18970 				strings = getstringarray(us_renamenetsa, &count);
18971 				if (us_renamenetindex >= count) break;
18972 				pt = strings[us_renamenetindex];
18973 				us_renamenetindex++;
18974 				if (us_renamenetindex > 1 &&
18975 					namesame(strings[us_renamenetindex-1], strings[us_renamenetindex-2]) == 0)
18976 						continue;
18977 				return(pt);
18978 			}
18979 	}
18980 	return(0);
18981 }
18982 
18983 /****************************** ROM GENERATION DIALOG ******************************/
18984 
18985 /* ROM Generator */
18986 static DIALOGITEM us_romgdialogitems[] =
18987 {
18988  /*  1 */ {0, {104,164,128,244}, BUTTON, N_("OK")},
18989  /*  2 */ {0, {104,48,128,128}, BUTTON, N_("Cancel")},
18990  /*  3 */ {0, {4,4,20,200}, MESSAGE, N_("ROM personality file:")},
18991  /*  4 */ {0, {24,4,56,296}, EDITTEXT, x_("")},
18992  /*  5 */ {0, {4,224,20,272}, BUTTON, N_("Set")},
18993  /*  6 */ {0, {72,4,88,176}, MESSAGE, N_("Gate size (nanometers):")},
18994  /*  7 */ {0, {72,180,88,272}, EDITTEXT, x_("")}
18995 };
18996 static DIALOG us_romgdialog = {{75,75,212,381}, N_("ROM Generation"), 0, 7, us_romgdialogitems, 0, 0};
18997 
18998 /* special items for the "ROM generation" dialog: */
18999 #define DROG_FILENAME        4		/* ROM personality file (edit text) */
19000 #define DSLO_SETFILE         5		/* set personality file (button) */
19001 #define DSLO_GATESIZE        7		/* gate size (edit text) */
19002 
us_romgendlog(void)19003 INTBIG us_romgendlog(void)
19004 {
19005 	REGISTER INTBIG itemHit, i, l, oldplease;
19006 	REGISTER void *dia, *infstr;
19007 	REGISTER CHAR *pt, *filename, *gatesize, *cellname;
19008 	CHAR *subparams[5], buf[50];
19009 
19010 	/* display the dialog box */
19011 	dia = DiaInitDialog(&us_romgdialog);
19012 	if (dia == 0) return(0);
19013 	esnprintf(buf, 50, x_("%ld"), el_curlib->lambda[el_curtech->techindex]);
19014 	DiaSetText(dia, DSLO_GATESIZE, buf);
19015 
19016 	/* loop until done */
19017 	for(;;)
19018 	{
19019 		itemHit = DiaNextHit(dia);
19020 		if (itemHit == OK || itemHit == CANCEL) break;
19021 		if (itemHit == DSLO_SETFILE)
19022 		{
19023 			/* set personality file */
19024 			oldplease = el_pleasestop;
19025 			infstr = initinfstr();
19026 			addstringtoinfstr(infstr, x_("text/"));
19027 			addstringtoinfstr(infstr, _("Personality File"));
19028 			i = ttygetparam(returninfstr(infstr), &us_colorreadp, 1, subparams);
19029 			el_pleasestop = oldplease;
19030 			if (i != 0 && subparams[0][0] != 0)
19031 				DiaSetText(dia, DROG_FILENAME, subparams[0]);
19032 			continue;
19033 		}
19034 	}
19035 
19036 	if (itemHit != CANCEL)
19037 	{
19038 		filename = DiaGetText(dia, DROG_FILENAME);
19039 		gatesize = DiaGetText(dia, DSLO_GATESIZE);
19040 		l = strlen(filename);
19041 		for(i=l-1; i>0; i--)
19042 			if (filename[i] == DIRSEP) break;
19043 		if (i > 0) i++;
19044 		infstr = initinfstr();
19045 		for(pt = &filename[i]; *pt != 0; pt++)
19046 		{
19047 			if (*pt == '.') break;
19048 			addtoinfstr(infstr, *pt);
19049 		}
19050 		cellname = returninfstr(infstr);
19051 		infstr = initinfstr();
19052 		addstringtoinfstr(infstr, x_("romgen.main(\""));
19053 		for(pt = filename; *pt != 0; pt++)
19054 		{
19055 			addtoinfstr(infstr, *pt);
19056 			if (*pt == '\\') addtoinfstr(infstr, *pt);
19057 		}
19058 		formatinfstr(infstr, x_("\", \"%s\", %s)"), cellname, gatesize);
19059 		pt = returninfstr(infstr);
19060 		ttyputmsg("Executing %s", pt);
19061 		(void)doquerry(pt, VJAVA, VINTEGER);
19062 	}
19063 	DiaDoneDialog(dia);
19064 	return(0);
19065 }
19066 
19067 /****************************** SELECTION: OPTIONS DIALOG ******************************/
19068 
19069 /* Selection Options */
19070 static DIALOGITEM us_seloptdialogitems[] =
19071 {
19072  /*  1 */ {0, {108,196,132,276}, BUTTON, N_("OK")},
19073  /*  2 */ {0, {108,4,132,84}, BUTTON, N_("Cancel")},
19074  /*  3 */ {0, {8,4,24,280}, CHECK, N_("Easy selection of cell instances")},
19075  /*  4 */ {0, {32,4,48,280}, CHECK, N_("Easy selection of annotation text")},
19076  /*  5 */ {0, {56,4,72,280}, CHECK, N_("Center-based primitives")},
19077  /*  6 */ {0, {80,4,96,280}, CHECK, N_("Dragging must enclose entire object")}
19078 };
19079 static DIALOG us_seloptdialog = {{75,75,216,365}, N_("Selection Options"), 0, 6, us_seloptdialogitems, 0, 0};
19080 
19081 /* special items for the "selection options" dialog: */
19082 #define DSLO_EASYINSTANCES   3		/* easy selection of instances (check) */
19083 #define DSLO_EASYANNOTATION  4		/* easy selection of annotation (check) */
19084 #define DSLO_CENTERPRIMS     5		/* Center-based primitives (check) */
19085 #define DSLO_DRAGMUSTENCLOSE 6		/* Dragging must enclose entire object (check) */
19086 
us_selectoptdlog(void)19087 INTBIG us_selectoptdlog(void)
19088 {
19089 	REGISTER INTBIG itemHit;
19090 	REGISTER INTBIG options;
19091 	REGISTER void *dia;
19092 
19093 	/* display the dialog box */
19094 	dia = DiaInitDialog(&us_seloptdialog);
19095 	if (dia == 0) return(0);
19096 	if ((us_useroptions&NOINSTANCESELECT) == 0) DiaSetControl(dia, DSLO_EASYINSTANCES, 1);
19097 	if ((us_useroptions&NOTEXTSELECT) == 0) DiaSetControl(dia, DSLO_EASYANNOTATION, 1);
19098 	if ((us_useroptions&CENTEREDPRIMITIVES) != 0) DiaSetControl(dia, DSLO_CENTERPRIMS, 1);
19099 	if ((us_useroptions&MUSTENCLOSEALL) != 0) DiaSetControl(dia, DSLO_DRAGMUSTENCLOSE, 1);
19100 
19101 	/* loop until done */
19102 	for(;;)
19103 	{
19104 		itemHit = DiaNextHit(dia);
19105 		if (itemHit == OK || itemHit == CANCEL) break;
19106 		if (itemHit == DSLO_EASYINSTANCES || itemHit == DSLO_EASYANNOTATION ||
19107 			itemHit == DSLO_CENTERPRIMS || itemHit == DSLO_DRAGMUSTENCLOSE)
19108 		{
19109 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
19110 			continue;
19111 		}
19112 	}
19113 
19114 	if (itemHit != CANCEL)
19115 	{
19116 		options = us_useroptions;
19117 		if (DiaGetControl(dia, DSLO_EASYINSTANCES) != 0) options &= ~NOINSTANCESELECT; else
19118 			options |= NOINSTANCESELECT;
19119 		if (DiaGetControl(dia, DSLO_EASYANNOTATION) != 0) options &= ~NOTEXTSELECT; else
19120 			options |= NOTEXTSELECT;
19121 		if (DiaGetControl(dia, DSLO_CENTERPRIMS) == 0) options &= ~CENTEREDPRIMITIVES; else
19122 			options |= CENTEREDPRIMITIVES;
19123 		if (DiaGetControl(dia, DSLO_DRAGMUSTENCLOSE) == 0) options &= ~MUSTENCLOSEALL; else
19124 			options |= MUSTENCLOSEALL;
19125 		if (options != us_useroptions)
19126 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, options, VINTEGER);
19127 	}
19128 	DiaDoneDialog(dia);
19129 	return(0);
19130 }
19131 
19132 /****************************** SELECTION: PORT/NODE/NET DIALOG ******************************/
19133 
19134 /* Selection: Export/Net/Node */
19135 static DIALOGITEM us_selnamedialogitems[] =
19136 {
19137  /*  1 */ {0, {192,60,216,140}, BUTTON, N_("Done")},
19138  /*  2 */ {0, {8,8,180,192}, SCROLLMULTI, x_("")}
19139 };
19140 static DIALOG us_selnamedialog = {{75,75,300,276}, N_("Select Port"), 0, 2, us_selnamedialogitems, 0, 0};
19141 
19142 /* special items for the "select export/net" dialog: */
19143 #define DSPN_LIST   2		/* export/net/node list (scroll) */
19144 
19145 static INTBIG     us_selportnodenet;
19146 static NETWORK   *us_selnet;
19147 static PORTPROTO *us_selport;
19148 static NODEINST  *us_selnode;
19149 static ARCINST   *us_selarc;
19150 
19151 static BOOLEAN us_topofobject(CHAR **c);
19152 static CHAR   *us_nextobject(void);
19153 
us_topofobject(CHAR ** c)19154 BOOLEAN us_topofobject(CHAR **c)
19155 {
19156 	Q_UNUSED( c );
19157 	REGISTER NODEPROTO *np;
19158 
19159 	np = us_needcell();
19160 	switch (us_selportnodenet)
19161 	{
19162 		case 0: us_selnet = np->firstnetwork;      break;
19163 		case 1: us_selport = np->firstportproto;   break;
19164 		case 2: us_selnode = np->firstnodeinst;    break;
19165 		case 3: us_selarc = np->firstarcinst;      break;
19166 	}
19167 	return(TRUE);
19168 }
19169 
us_nextobject(void)19170 CHAR *us_nextobject(void)
19171 {
19172 	REGISTER CHAR *retname;
19173 	static CHAR genname[100];
19174 	REGISTER NETWORK *retnet;
19175 	REGISTER NODEINST *retnode;
19176 	REGISTER ARCINST *retarc;
19177 	REGISTER VARIABLE *var;
19178 
19179 	switch (us_selportnodenet)
19180 	{
19181 		case 0:		/* network */
19182 			if (us_selnet == NONETWORK) break;
19183 			retnet = us_selnet;
19184 			us_selnet = us_selnet->nextnetwork;
19185 			if (retnet->globalnet >= 0) return(describenetwork(retnet));
19186 			if (retnet->namecount != 0) return(networkname(retnet, 0));
19187 			esnprintf(genname, 100, x_("NET%ld"), (INTBIG)retnet);
19188 			return(genname);
19189 		case 1:		/* port */
19190 			if (us_selport == NOPORTPROTO) break;
19191 			retname = us_selport->protoname;
19192 			us_selport = us_selport->nextportproto;
19193 			return(retname);
19194 		case 2:		/* node */
19195 			for(;;)
19196 			{
19197 				if (us_selnode == NONODEINST) return(0);
19198 				retnode = us_selnode;
19199 				us_selnode = us_selnode->nextnodeinst;
19200 				var = getvalkey((INTBIG)retnode, VNODEINST, VSTRING, el_node_name_key);
19201 				if (var != NOVARIABLE) break;
19202 			}
19203 			return((CHAR *)var->addr);
19204 		case 3:		/* arc */
19205 			for(;;)
19206 			{
19207 				if (us_selarc == NOARCINST) return(0);
19208 				retarc = us_selarc;
19209 				us_selarc = us_selarc->nextarcinst;
19210 				var = getvalkey((INTBIG)retarc, VARCINST, VSTRING, el_arc_name_key);
19211 				if (var != NOVARIABLE) break;
19212 			}
19213 			return((CHAR *)var->addr);
19214 	}
19215 	return(0);
19216 }
19217 
19218 /*
19219  * special code for the "selection object" dialog
19220  * "selport" is: 0=network, 1=port, 2=node, 3=arc
19221  */
us_selectobjectdlog(INTBIG selportnodenet)19222 INTBIG us_selectobjectdlog(INTBIG selportnodenet)
19223 {
19224 	REGISTER INTBIG itemHit, *whichlist, which, i, j;
19225 	REGISTER BOOLEAN first;
19226 	REGISTER NODEPROTO *np;
19227 	REGISTER PORTPROTO *pp;
19228 	REGISTER NODEINST *ni;
19229 	REGISTER ARCINST *ai;
19230 	REGISTER NETWORK *net, **netlist;
19231 	REGISTER VARIABLE *var;
19232 	REGISTER CHAR *pt;
19233 	REGISTER void *infstr;
19234 	REGISTER void *dia;
19235 
19236 	np = us_needcell();
19237 	if (np == NONODEPROTO) return(0);
19238 
19239 	/* display the dialog box */
19240 	us_selportnodenet = selportnodenet;
19241 	switch (selportnodenet)
19242 	{
19243 		case 0: us_selnamedialog.movable = _("Select Network");   break;
19244 		case 1: us_selnamedialog.movable = _("Select Export");    break;
19245 		case 2: us_selnamedialog.movable = _("Select Node");      break;
19246 		case 3: us_selnamedialog.movable = _("Select Arc");       break;
19247 	}
19248 	dia = DiaInitDialog(&us_selnamedialog);
19249 	if (dia == 0) return(0);
19250 	DiaInitTextDialog(dia, DSPN_LIST, us_topofobject, us_nextobject, DiaNullDlogDone, 0,
19251 		SCSELMOUSE|SCREPORT);
19252 
19253 	/* loop until done */
19254 	for(;;)
19255 	{
19256 		itemHit = DiaNextHit(dia);
19257 		if (itemHit == OK) break;
19258 		if (itemHit == DSPN_LIST)
19259 		{
19260 			whichlist = DiaGetCurLines(dia, DSPN_LIST);
19261 			if (whichlist[0] < 0) continue;
19262 			infstr = initinfstr();
19263 			first = FALSE;
19264 			for(i=0; whichlist[i] >= 0; i++)
19265 			{
19266 				which = whichlist[i];
19267 				pt = DiaGetScrollLine(dia, DSPN_LIST, which);
19268 				switch (selportnodenet)
19269 				{
19270 					case 0:		/* find network */
19271 						netlist = getcomplexnetworks(pt, np);
19272 						for(j=0; netlist[j] != NONETWORK; j++)
19273 						{
19274 							net = netlist[j];
19275 							for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
19276 							{
19277 								if (ai->network != net) continue;
19278 								if (first) addtoinfstr(infstr, '\n');
19279 								first = TRUE;
19280 								formatinfstr(infstr, x_("CELL=%s FROM=0%lo;-1;0"),
19281 									describenodeproto(np), (INTBIG)ai->geom);
19282 							}
19283 						}
19284 						break;
19285 					case 1:		/* find port */
19286 						pp = getportproto(np, pt);
19287 						if (pp != NOPORTPROTO)
19288 						{
19289 							if (first) addtoinfstr(infstr, '\n');
19290 							first = TRUE;
19291 							formatinfstr(infstr, x_("CELL=%s TEXT=0%lo;0%lo;0"),
19292 								describenodeproto(np), (INTBIG)pp->subnodeinst->geom,
19293 									(INTBIG)pp);
19294 						}
19295 						break;
19296 					case 2:		/* find node */
19297 						for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
19298 						{
19299 							var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
19300 							if (var == NOVARIABLE) continue;
19301 							if (namesame(pt, (CHAR *)var->addr) != 0) continue;
19302 							if (first) addtoinfstr(infstr, '\n');
19303 							first = TRUE;
19304 							formatinfstr(infstr, x_("CELL=%s FROM=0%lo;-1;0"),
19305 								describenodeproto(np), (INTBIG)ni->geom);
19306 							break;
19307 						}
19308 						break;
19309 					case 3:		/* find arc */
19310 						for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
19311 						{
19312 							var = getvalkey((INTBIG)ai, VARCINST, VSTRING, el_arc_name_key);
19313 							if (var == NOVARIABLE) continue;
19314 							if (namesame(pt, (CHAR *)var->addr) != 0) continue;
19315 							if (first) addtoinfstr(infstr, '\n');
19316 							first = TRUE;
19317 							formatinfstr(infstr, x_("CELL=%s FROM=0%lo;-1;0"),
19318 								describenodeproto(np), (INTBIG)ai->geom);
19319 							break;
19320 						}
19321 						break;
19322 				}
19323 			}
19324 			us_setmultiplehighlight(returninfstr(infstr), FALSE);
19325 			us_showallhighlight();
19326 			us_endchanges(NOWINDOWPART);
19327 		}
19328 	}
19329 	DiaDoneDialog(dia);
19330 	return(0);
19331 }
19332 
19333 /****************************** SPREAD DIALOG ******************************/
19334 
19335 /* Spread */
19336 static DIALOGITEM us_spreaddialogitems[] =
19337 {
19338  /*  1 */ {0, {96,128,120,200}, BUTTON, N_("OK")},
19339  /*  2 */ {0, {96,16,120,88}, BUTTON, N_("Cancel")},
19340  /*  3 */ {0, {55,15,71,205}, EDITTEXT, x_("")},
19341  /*  4 */ {0, {20,230,36,380}, RADIO, N_("Spread up")},
19342  /*  5 */ {0, {45,230,61,380}, RADIO, N_("Spread down")},
19343  /*  6 */ {0, {70,230,86,380}, RADIO, N_("Spread left")},
19344  /*  7 */ {0, {95,230,111,380}, RADIO, N_("Spread right")},
19345  /*  8 */ {0, {25,15,41,180}, MESSAGE, N_("Distance to spread")}
19346 };
19347 static DIALOG us_spreaddialog = {{50,75,188,464}, N_("Spread About Highlighted"), 0, 8, us_spreaddialogitems, 0, 0};
19348 
19349 /* special items for the "spread" dialog: */
19350 #define DSPR_DISTANCE  3		/* Distance (edit text) */
19351 #define DSPR_UP        4		/* Up (radio) */
19352 #define DSPR_DOWN      5		/* Down (radio) */
19353 #define DSPR_LEFT      6		/* Left (radio) */
19354 #define DSPR_RIGHT     7		/* Right (radio) */
19355 
us_spreaddlog(void)19356 INTBIG us_spreaddlog(void)
19357 {
19358 	CHAR *param[2];
19359 	INTBIG itemHit;
19360 	static INTBIG lastamount = WHOLE;
19361 	static INTBIG defdir  = DSPR_UP;
19362 	REGISTER void *dia;
19363 
19364 	/* display the spread dialog box */
19365 	dia = DiaInitDialog(&us_spreaddialog);
19366 	if (dia == 0) return(0);
19367 
19368 	/* "up" is the default direction, distance is 1 */
19369 	DiaSetText(dia, -DSPR_DISTANCE, frtoa(lastamount));
19370 	DiaSetControl(dia, defdir, 1);
19371 
19372 	/* loop until done */
19373 	for(;;)
19374 	{
19375 		itemHit = DiaNextHit(dia);
19376 		if (itemHit == CANCEL) break;
19377 		if (itemHit == OK && DiaValidEntry(dia, DSPR_DISTANCE)) break;
19378 		if (itemHit == DSPR_UP || itemHit == DSPR_DOWN ||
19379 			itemHit == DSPR_LEFT || itemHit == DSPR_RIGHT)
19380 		{
19381 			DiaSetControl(dia, DSPR_UP, 0);
19382 			DiaSetControl(dia, DSPR_DOWN, 0);
19383 			DiaSetControl(dia, DSPR_LEFT, 0);
19384 			DiaSetControl(dia, DSPR_RIGHT, 0);
19385 			DiaSetControl(dia, itemHit, 1);
19386 			continue;
19387 		}
19388 	}
19389 
19390 	if (itemHit != CANCEL)
19391 	{
19392 		if (DiaGetControl(dia, DSPR_UP) != 0)
19393 		{
19394 			defdir = DSPR_UP;   param[0] = x_("up");
19395 		} else if (DiaGetControl(dia, DSPR_DOWN) != 0)
19396 		{
19397 			defdir = DSPR_DOWN;   param[0] = x_("down");
19398 		} else if (DiaGetControl(dia, DSPR_LEFT) != 0)
19399 		{
19400 			defdir = DSPR_LEFT;   param[0] = x_("left");
19401 		} else if (DiaGetControl(dia, DSPR_RIGHT) != 0)
19402 		{
19403 			defdir = DSPR_RIGHT;   param[0] = x_("right");
19404 		}
19405 		param[1] = DiaGetText(dia, DSPR_DISTANCE);
19406 		lastamount = atofr(param[1]);
19407 		us_spread(2, param);
19408 	}
19409 	DiaDoneDialog(dia);
19410 	return(0);
19411 }
19412 
19413 /****************************** TECHNOLOGY EDIT: CONVERT LIBRARY TO TECHNOLOGY ******************************/
19414 
19415 /* Technology Edit: Convert Library */
19416 static DIALOGITEM us_tecedlibtotechdialogitems[] =
19417 {
19418  /*  1 */ {0, {96,284,120,364}, BUTTON, N_("OK")},
19419  /*  2 */ {0, {96,16,120,96}, BUTTON, N_("Cancel")},
19420  /*  3 */ {0, {88,120,104,252}, CHECK, N_("Also write C code")},
19421  /*  4 */ {0, {8,8,24,224}, MESSAGE, N_("Creating new technology:")},
19422  /*  5 */ {0, {8,228,24,372}, EDITTEXT, x_("")},
19423  /*  6 */ {0, {40,8,56,372}, MESSAGE, N_("Already a technology with this name")},
19424  /*  7 */ {0, {64,8,80,224}, MESSAGE, N_("Rename existing technology to:")},
19425  /*  8 */ {0, {64,228,80,372}, EDITTEXT, x_("")},
19426  /*  9 */ {0, {112,120,128,272}, CHECK, N_("Also write Java code")}
19427 };
19428 static DIALOG us_tecedlibtotechdialog = {{75,75,212,457}, N_("Convert Library to Technology"), 0, 9, us_tecedlibtotechdialogitems, 0, 0};
19429 
19430 /* special items for the "convert library to technology" dialog: */
19431 #define DLTT_WRITECCODE     3		/* Write C code (check) */
19432 #define DLTT_TECHNAME       5		/* New tech name (edit text) */
19433 #define DLTT_EXISTWARN_L1   6		/* Warning that tech exists (stat text) */
19434 #define DLTT_EXISTWARN_L2   7		/* Warning that tech exists (stat text) */
19435 #define DLTT_RENAME         8		/* New name of existing technology (edit text) */
19436 #define DLTT_WRITEJAVACCODE 9		/* Write Java code (check) */
19437 
us_libtotechnologydlog(void)19438 INTBIG us_libtotechnologydlog(void)
19439 {
19440 	INTBIG itemHit;
19441 	BOOLEAN checkforconflict, conflicts;
19442 	CHAR *par[5], *pt;
19443 	REGISTER TECHNOLOGY *tech;
19444 	REGISTER void *dia;
19445 
19446 	/* display the dependent library dialog box */
19447 	dia = DiaInitDialog(&us_tecedlibtotechdialog);
19448 	if (dia == 0) return(0);
19449 	DiaSetText(dia, DLTT_TECHNAME, el_curlib->libname);
19450 
19451 	/* loop until done */
19452 	checkforconflict = TRUE;
19453 	for(;;)
19454 	{
19455 		if (checkforconflict)
19456 		{
19457 			checkforconflict = FALSE;
19458 			pt = DiaGetText(dia, DLTT_TECHNAME);
19459 			for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
19460 				if (namesame(tech->techname, pt) == 0) break;
19461 			if (tech == NOTECHNOLOGY)
19462 			{
19463 				DiaDimItem(dia, DLTT_EXISTWARN_L1);
19464 				DiaDimItem(dia, DLTT_EXISTWARN_L2);
19465 				DiaSetText(dia, DLTT_RENAME, x_(""));
19466 				DiaDimItem(dia, DLTT_RENAME);
19467 				conflicts = FALSE;
19468 			} else
19469 			{
19470 				DiaUnDimItem(dia, DLTT_EXISTWARN_L1);
19471 				DiaUnDimItem(dia, DLTT_EXISTWARN_L2);
19472 				DiaUnDimItem(dia, DLTT_RENAME);
19473 				conflicts = TRUE;
19474 			}
19475 		}
19476 		itemHit = DiaNextHit(dia);
19477 		if (itemHit == CANCEL) break;
19478 		if (itemHit == OK)
19479 		{
19480 			if (conflicts)
19481 			{
19482 				if (!DiaValidEntry(dia, DLTT_RENAME)) continue;
19483 			}
19484 			break;
19485 		}
19486 		if (itemHit == DLTT_TECHNAME)
19487 		{
19488 			checkforconflict = TRUE;
19489 			continue;
19490 		}
19491 		if (itemHit == DLTT_WRITECCODE)
19492 		{
19493 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
19494 			DiaSetControl(dia, DLTT_WRITEJAVACCODE, 0);
19495 			continue;
19496 		}
19497 		if (itemHit == DLTT_WRITEJAVACCODE)
19498 		{
19499 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
19500 			continue;
19501 		}
19502 	}
19503 
19504 	if (itemHit != CANCEL)
19505 	{
19506 		if (conflicts)
19507 		{
19508 			par[0] = DiaGetText(dia, DLTT_TECHNAME);
19509 			par[1] = DiaGetText(dia, DLTT_RENAME);
19510 			par[2] = x_("t");
19511 			us_rename(3, par);
19512 		}
19513 		par[0] = x_("edit");
19514 		if (DiaGetControl(dia, DLTT_WRITECCODE) != 0) par[1] = x_("library-to-tech-and-C"); else
19515 		{
19516 			if (DiaGetControl(dia, DLTT_WRITEJAVACCODE) != 0) par[1] = x_("library-to-tech-and-Java"); else
19517 				par[1] = x_("library-to-tech");
19518 		}
19519 		par[2] = DiaGetText(dia, DLTT_TECHNAME);
19520 		us_technology(3, par);
19521 	}
19522 	DiaDoneDialog(dia);
19523 	return(0);
19524 }
19525 
19526 /****************************** TECHNOLOGY EDIT: DEPENDENT LIBRARIES DIALOG ******************************/
19527 
19528 /* Dependent Libraries */
19529 static DIALOGITEM us_dependentlibdialogitems[] =
19530 {
19531  /*  1 */ {0, {208,368,232,432}, BUTTON, N_("OK")},
19532  /*  2 */ {0, {208,256,232,320}, BUTTON, N_("Cancel")},
19533  /*  3 */ {0, {32,8,177,174}, SCROLL, x_("")},
19534  /*  4 */ {0, {8,8,24,153}, MESSAGE, N_("Dependent Libraries:")},
19535  /*  5 */ {0, {208,8,224,165}, MESSAGE, N_("Libraries are examined")},
19536  /*  6 */ {0, {40,192,64,256}, BUTTON, N_("Remove")},
19537  /*  7 */ {0, {88,192,112,256}, BUTTON, N_("<< Add")},
19538  /*  8 */ {0, {128,280,144,427}, MESSAGE, N_("Library (if not in list):")},
19539  /*  9 */ {0, {152,280,168,432}, EDITTEXT, x_("")},
19540  /* 10 */ {0, {8,272,24,361}, MESSAGE, N_("All Libraries:")},
19541  /* 11 */ {0, {224,8,240,123}, MESSAGE, N_("from bottom up")},
19542  /* 12 */ {0, {32,272,118,438}, SCROLL, x_("")},
19543  /* 13 */ {0, {184,8,200,67}, MESSAGE, N_("Current:")},
19544  /* 14 */ {0, {184,72,200,254}, MESSAGE, x_("")}
19545 };
19546 static DIALOG us_dependentlibdialog = {{50,75,299,524}, N_("Dependent Library Selection"), 0, 14, us_dependentlibdialogitems, 0, 0};
19547 
19548 static void us_showliblist(CHAR**, INTBIG, void*);
19549 
19550 /* special items for the "dependent libraries" dialog: */
19551 #define DTED_DEPENDENTLIST  3		/* Dependent list (scroll) */
19552 #define DTED_REMOVELIB      6		/* Remove lib (button) */
19553 #define DTED_ADDLIB         7		/* Add lib (button) */
19554 #define DTED_NEWNAME        9		/* New name (edit text) */
19555 #define DTED_LIBLIST       12		/* Library list (scroll) */
19556 #define DTED_CURRENTLIB    14		/* Current lib (stat text) */
19557 
us_dependentlibdlog(void)19558 INTBIG us_dependentlibdlog(void)
19559 {
19560 	INTBIG itemHit, i, j, liblistlen;
19561 	REGISTER VARIABLE *var;
19562 	CHAR **liblist, **newliblist, *pt;
19563 	REGISTER void *dia;
19564 
19565 	/* display the dependent library dialog box */
19566 	dia = DiaInitDialog(&us_dependentlibdialog);
19567 	if (dia == 0) return(0);
19568 	DiaSetText(dia, DTED_CURRENTLIB, el_curlib->libname);
19569 	DiaInitTextDialog(dia, DTED_LIBLIST, topoflibs, nextlibs, DiaNullDlogDone, 0, SCSELMOUSE|SCSELKEY);
19570 	DiaInitTextDialog(dia, DTED_DEPENDENTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
19571 		SCSELMOUSE|SCSELKEY);
19572 	var = getval((INTBIG)el_curlib, VLIBRARY, VSTRING|VISARRAY, x_("EDTEC_dependent_libraries"));
19573 	if (var == NOVARIABLE) liblistlen = 0; else
19574 	{
19575 		liblistlen = getlength(var);
19576 		liblist = (CHAR **)emalloc(liblistlen * (sizeof (CHAR *)), el_tempcluster);
19577 		if (liblist == 0) return(0);
19578 		for(i=0; i<liblistlen; i++)
19579 			(void)allocstring(&liblist[i], ((CHAR **)var->addr)[i], el_tempcluster);
19580 	}
19581 	us_showliblist(liblist, liblistlen, dia);
19582 
19583 	/* loop until done */
19584 	for(;;)
19585 	{
19586 		itemHit = DiaNextHit(dia);
19587 		if (itemHit == CANCEL || itemHit == OK) break;
19588 		if (itemHit == DTED_REMOVELIB)
19589 		{
19590 			/* remove */
19591 			i = DiaGetCurLine(dia, DTED_DEPENDENTLIST);
19592 			if (i < 0 || i >= liblistlen) continue;
19593 			efree(liblist[i]);
19594 			for(j=i; j<liblistlen-1; j++) liblist[j] = liblist[j+1];
19595 			liblistlen--;
19596 			if (liblistlen == 0) efree((CHAR *)liblist);
19597 			us_showliblist(liblist, liblistlen, dia);
19598 			continue;
19599 		}
19600 		if (itemHit == DTED_ADDLIB)
19601 		{
19602 			/* add */
19603 			pt = DiaGetText(dia, DTED_NEWNAME);
19604 			while (*pt == ' ') pt++;
19605 			if (*pt == 0) pt = DiaGetScrollLine(dia, DTED_LIBLIST, DiaGetCurLine(dia, DTED_LIBLIST));
19606 			i = DiaGetCurLine(dia, DTED_DEPENDENTLIST);
19607 			if (i < 0) i = 0;
19608 
19609 			/* create a new list */
19610 			newliblist = (CHAR **)emalloc((liblistlen+1) * (sizeof (CHAR *)), el_tempcluster);
19611 			if (newliblist == 0) return(0);
19612 			for(j=0; j<liblistlen; j++) newliblist[j] = liblist[j];
19613 			if (liblistlen != 0) efree((CHAR *)liblist);
19614 			liblist = newliblist;
19615 
19616 			for(j=liblistlen; j>i; j--) liblist[j] = liblist[j-1];
19617 			liblistlen++;
19618 			(void)allocstring(&liblist[i], pt, el_tempcluster);
19619 			us_showliblist(liblist, liblistlen, dia);
19620 			DiaSetText(dia, DTED_NEWNAME, x_(""));
19621 			continue;
19622 		}
19623 	}
19624 
19625 	if (itemHit != CANCEL)
19626 	{
19627 		if (liblistlen == 0)
19628 		{
19629 			if (var != NOVARIABLE)
19630 				(void)delval((INTBIG)el_curlib, VLIBRARY, x_("EDTEC_dependent_libraries"));
19631 		} else
19632 		{
19633 			(void)setval((INTBIG)el_curlib, VLIBRARY, x_("EDTEC_dependent_libraries"),
19634 				(INTBIG)liblist, VSTRING|VISARRAY|(liblistlen<<VLENGTHSH));
19635 		}
19636 	}
19637 	for(i=0; i<liblistlen; i++) efree(liblist[i]);
19638 	if (liblistlen != 0) efree((CHAR *)liblist);
19639 	DiaDoneDialog(dia);
19640 	return(0);
19641 }
19642 
us_showliblist(CHAR ** liblist,INTBIG liblistlen,void * dia)19643 void us_showliblist(CHAR **liblist, INTBIG liblistlen, void *dia)
19644 {
19645 	REGISTER INTBIG i;
19646 
19647 	DiaLoadTextDialog(dia, DTED_DEPENDENTLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
19648 	if (liblistlen == 0)
19649 	{
19650 		DiaSelectLine(dia, DTED_DEPENDENTLIST, -1);
19651 		return;
19652 	}
19653 	for(i=0; i<liblistlen; i++) DiaStuffLine(dia, DTED_DEPENDENTLIST, liblist[i]);
19654 	DiaSelectLine(dia, DTED_DEPENDENTLIST, 0);
19655 }
19656 
19657 /****************************** TECHNOLOGY EDIT: VARIABLES DIALOG ******************************/
19658 
19659 /* Technology Variables */
19660 static DIALOGITEM us_techvarsdialogitems[] =
19661 {
19662  /*  1 */ {0, {208,472,232,536}, BUTTON, N_("OK")},
19663  /*  2 */ {0, {208,376,232,440}, BUTTON, N_("Cancel")},
19664  /*  3 */ {0, {24,8,143,264}, SCROLL, x_("")},
19665  /*  4 */ {0, {176,16,192,55}, MESSAGE, N_("Type:")},
19666  /*  5 */ {0, {176,56,192,142}, MESSAGE, x_("")},
19667  /*  6 */ {0, {152,104,168,536}, MESSAGE, x_("")},
19668  /*  7 */ {0, {24,280,143,536}, SCROLL, x_("")},
19669  /*  8 */ {0, {8,16,24,240}, MESSAGE, N_("Current Variables on Technology:")},
19670  /*  9 */ {0, {8,288,24,419}, MESSAGE, N_("Possible Variables:")},
19671  /* 10 */ {0, {208,280,232,344}, BUTTON, N_("<< Copy")},
19672  /* 11 */ {0, {208,24,232,88}, BUTTON, N_("Remove")},
19673  /* 12 */ {0, {176,216,192,533}, EDITTEXT, x_("")},
19674  /* 13 */ {0, {208,136,232,237}, BUTTON, N_("Edit Strings")},
19675  /* 14 */ {0, {176,168,192,212}, MESSAGE, N_("Value:")},
19676  /* 15 */ {0, {152,16,168,98}, MESSAGE, N_("Description:")}
19677 };
19678 static DIALOG us_techvarsdialog = {{50,75,293,622}, N_("Technology Variables"), 0, 15, us_techvarsdialogitems, 0, 0};
19679 
19680 static void us_setcurrenttechvar(TECHVAR*, void*);
19681 
19682 /* special items for the "technology variables" dialog: */
19683 #define DTEV_CURVARS      3		/* Current vars (scroll) */
19684 #define DTEV_TYPE         5		/* Type (stat text) */
19685 #define DTEV_DESCRIPTION  6		/* Description (stat text) */
19686 #define DTEV_ALLVARS      7		/* Known vars (scroll) */
19687 #define DTEV_COPY        10		/* Copy (button) */
19688 #define DTEV_REMOVE      11		/* Remove (button) */
19689 #define DTEV_VALUE       12		/* the Value (edit text) */
19690 #define DTEV_EDITSTRINGS 13		/* Edit Strings (button) */
19691 
us_techvarsdlog(void)19692 INTBIG us_techvarsdlog(void)
19693 {
19694 	CHAR **varnames, *name, *cmd[5];
19695 	INTBIG itemHit, i, j;
19696 	REGISTER VARIABLE *var, *ovar;
19697 	TECHVAR *newvars, *tvar, *ltvar, *t;
19698 	REGISTER void *infstr;
19699 	REGISTER void *dia;
19700 
19701 	/* show the "technology variables" dialog */
19702 	dia = DiaInitDialog(&us_techvarsdialog);
19703 	if (dia == 0) return(0);
19704 	DiaInitTextDialog(dia, DTEV_CURVARS, DiaNullDlogList, DiaNullDlogItem,
19705 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
19706 	DiaInitTextDialog(dia, DTEV_ALLVARS, DiaNullDlogList, DiaNullDlogItem,
19707 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
19708 
19709 	/* load the known variables list */
19710 	for(i=0; us_knownvars[i].varname != 0; i++)
19711 		DiaStuffLine(dia, DTEV_ALLVARS, us_knownvars[i].varname);
19712 	DiaSelectLine(dia, DTEV_ALLVARS, -1);
19713 
19714 	/* see what variables are already in the list */
19715 	var = getval((INTBIG)el_curlib, VLIBRARY, VSTRING|VISARRAY, x_("EDTEC_variable_list"));
19716 	newvars = NOTECHVAR;
19717 	if (var != NOVARIABLE)
19718 	{
19719 		j = getlength(var);
19720 		varnames = (CHAR **)var->addr;
19721 		for(i=0; i<j; i++)
19722 		{
19723 			ovar = getval((INTBIG)el_curlib, VLIBRARY, -1, varnames[i]);
19724 			if (ovar == NOVARIABLE) continue;
19725 			DiaStuffLine(dia, DTEV_CURVARS, varnames[i]);
19726 			tvar = (TECHVAR *)emalloc(sizeof (TECHVAR), el_tempcluster);
19727 			if (tvar == 0) break;
19728 			(void)allocstring(&tvar->varname, varnames[i], el_tempcluster);
19729 			tvar->nexttechvar = newvars;
19730 			tvar->changed = FALSE;
19731 			switch (ovar->type&(VTYPE|VISARRAY))
19732 			{
19733 				case VFLOAT:   tvar->fval = castfloat(ovar->addr);   break;
19734 				case VINTEGER: tvar->ival = ovar->addr;              break;
19735 				case VSTRING:
19736 					(void)allocstring(&tvar->sval, (CHAR *)ovar->addr, el_tempcluster);
19737 					break;
19738 			}
19739 			tvar->vartype = ovar->type;
19740 			newvars = tvar;
19741 		}
19742 	}
19743 	DiaSelectLine(dia, DTEV_CURVARS, -1);
19744 
19745 	/* set dialog allowances state */
19746 	us_setcurrenttechvar(newvars, dia);
19747 	for(;;)
19748 	{
19749 		itemHit = DiaNextHit(dia);
19750 		if (itemHit == OK || itemHit == CANCEL ||
19751 			itemHit == DTEV_EDITSTRINGS) break;
19752 
19753 		/* hit in one scroll area turns off highlight in the other */
19754 		if (itemHit == DTEV_CURVARS)
19755 		{
19756 			DiaSelectLine(dia, DTEV_ALLVARS, -1);
19757 			us_setcurrenttechvar(newvars, dia);
19758 		}
19759 		if (itemHit == DTEV_ALLVARS)
19760 		{
19761 			DiaSelectLine(dia, DTEV_CURVARS, -1);
19762 			us_setcurrenttechvar(newvars, dia);
19763 		}
19764 		/* change to the value */
19765 		if (itemHit == DTEV_VALUE)
19766 		{
19767 			i = DiaGetCurLine(dia, DTEV_CURVARS);
19768 			if (i < 0) continue;
19769 			name = DiaGetScrollLine(dia, DTEV_CURVARS, i);
19770 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19771 				if (namesame(t->varname, name) == 0) break;
19772 			if (t == NOTECHVAR) continue;
19773 			switch (t->vartype&(VTYPE|VISARRAY))
19774 			{
19775 				case VINTEGER:
19776 					t->ival = myatoi(DiaGetText(dia, DTEV_VALUE));
19777 					t->changed = TRUE;
19778 					break;
19779 				case VFLOAT:
19780 					t->fval = (float)eatof(DiaGetText(dia, DTEV_VALUE));
19781 					t->changed = TRUE;
19782 					break;
19783 				case VSTRING:
19784 					(void)reallocstring(&t->sval, DiaGetText(dia, DTEV_VALUE), el_tempcluster);
19785 					t->changed = TRUE;
19786 					break;
19787 			}
19788 			continue;
19789 		}
19790 
19791 		/* the "<< Copy" button */
19792 		if (itemHit == DTEV_COPY)
19793 		{
19794 			i = DiaGetCurLine(dia, DTEV_ALLVARS);
19795 			if (i < 0) continue;
19796 			name = DiaGetScrollLine(dia, DTEV_ALLVARS, i);
19797 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19798 				if (namesame(t->varname, name) == 0) break;
19799 			if (t != NOTECHVAR) continue;
19800 
19801 			tvar = (TECHVAR *)emalloc(sizeof (TECHVAR), el_tempcluster);
19802 			if (tvar == 0) break;
19803 			(void)allocstring(&tvar->varname, name, el_tempcluster);
19804 			tvar->vartype = us_knownvars[i].vartype;
19805 			tvar->ival = 0;
19806 			tvar->fval = 0.0;
19807 			if ((tvar->vartype&(VTYPE|VISARRAY)) == VSTRING)
19808 				(void)allocstring(&tvar->sval, x_(""), el_tempcluster);
19809 			tvar->changed = TRUE;
19810 			tvar->nexttechvar = newvars;
19811 			newvars = tvar;
19812 			DiaLoadTextDialog(dia, DTEV_CURVARS, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
19813 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19814 				DiaStuffLine(dia, DTEV_CURVARS, t->varname);
19815 			DiaSelectLine(dia, DTEV_CURVARS, -1);
19816 			us_setcurrenttechvar(newvars, dia);
19817 			continue;
19818 		}
19819 
19820 		/* the "Remove" button */
19821 		if (itemHit == DTEV_REMOVE)
19822 		{
19823 			i = DiaGetCurLine(dia, DTEV_CURVARS);
19824 			if (i < 0) continue;
19825 			name = DiaGetScrollLine(dia, DTEV_CURVARS, i);
19826 
19827 			ltvar = NOTECHVAR;
19828 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19829 			{
19830 				if (namesame(t->varname, name) == 0) break;
19831 				ltvar = t;
19832 			}
19833 			if (t == NOTECHVAR) continue;
19834 			if (ltvar == NOTECHVAR) newvars = t->nexttechvar; else
19835 				ltvar->nexttechvar = t->nexttechvar;
19836 			if ((t->vartype&(VTYPE|VISARRAY)) == VSTRING) efree(t->sval);
19837 			efree(t->varname);
19838 			efree((CHAR *)t);
19839 			DiaLoadTextDialog(dia, DTEV_CURVARS, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
19840 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19841 				DiaStuffLine(dia, DTEV_CURVARS, t->varname);
19842 			DiaSelectLine(dia, DTEV_CURVARS, -1);
19843 			us_setcurrenttechvar(newvars, dia);
19844 			continue;
19845 		}
19846 	}
19847 	if (itemHit == DTEV_EDITSTRINGS)
19848 	{
19849 		i = DiaGetCurLine(dia, DTEV_CURVARS);
19850 		if (i < 0) itemHit = OK; else
19851 			name = DiaGetScrollLine(dia, DTEV_CURVARS, i);
19852 	}
19853 	DiaDoneDialog(dia);
19854 	if (itemHit == OK || itemHit == DTEV_EDITSTRINGS)
19855 	{
19856 		j = 0;
19857 		for(t = newvars; t != NOTECHVAR; t = t->nexttechvar) j++;
19858 		if (j > 0)
19859 		{
19860 			varnames = (CHAR **)emalloc(j * (sizeof (CHAR *)), el_tempcluster);
19861 			if (varnames == 0) return(0);
19862 			j = 0;
19863 			for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19864 			{
19865 				(void)allocstring(&varnames[j], t->varname, el_tempcluster);
19866 				j++;
19867 				if (!t->changed) continue;
19868 				switch (t->vartype&(VTYPE|VISARRAY))
19869 				{
19870 					case VINTEGER:
19871 						(void)setval((INTBIG)el_curlib, VLIBRARY, t->varname,
19872 							t->ival, VINTEGER);
19873 						break;
19874 					case VFLOAT:
19875 						(void)setval((INTBIG)el_curlib, VLIBRARY, t->varname,
19876 							castint(t->fval), VFLOAT);
19877 						break;
19878 					case VSTRING:
19879 						(void)setval((INTBIG)el_curlib, VLIBRARY, t->varname,
19880 							(INTBIG)t->sval, VSTRING);
19881 						break;
19882 					case VSTRING|VISARRAY:
19883 						cmd[0] = x_("EMPTY");
19884 						(void)setval((INTBIG)el_curlib, VLIBRARY, t->varname,
19885 							(INTBIG)cmd, VSTRING|VISARRAY|(1<<VLENGTHSH));
19886 						break;
19887 				}
19888 			}
19889 			(void)setval((INTBIG)el_curlib, VLIBRARY, x_("EDTEC_variable_list"),
19890 				(INTBIG)varnames, VSTRING|VISARRAY|(j<<VLENGTHSH));
19891 			for(i=0; i<j; i++) efree(varnames[i]);
19892 			efree((CHAR *)varnames);
19893 		} else
19894 		{
19895 			if (getval((INTBIG)el_curlib, VLIBRARY, VSTRING|VISARRAY, x_("EDTEC_variable_list")) != NOVARIABLE)
19896 				(void)delval((INTBIG)el_curlib, VLIBRARY, x_("EDTEC_variable_list"));
19897 		}
19898 	}
19899 	if (itemHit == DTEV_EDITSTRINGS)
19900 	{
19901 		cmd[0] = x_("textedit");
19902 		infstr = initinfstr();
19903 		addstringtoinfstr(infstr, x_("lib:~."));
19904 		addstringtoinfstr(infstr, name);
19905 		(void)allocstring(&cmd[1], returninfstr(infstr), el_tempcluster);
19906 		cmd[2] = x_("header");
19907 		infstr = initinfstr();
19908 		addstringtoinfstr(infstr, _("Editing technology variable: "));
19909 		addstringtoinfstr(infstr, name);
19910 		(void)allocstring(&cmd[3], returninfstr(infstr), el_tempcluster);
19911 		us_var(4, cmd);
19912 		efree(cmd[1]);
19913 		efree(cmd[3]);
19914 	}
19915 	return(0);
19916 }
19917 
us_setcurrenttechvar(TECHVAR * newvars,void * dia)19918 void us_setcurrenttechvar(TECHVAR *newvars, void *dia)
19919 {
19920 	TECHVAR *t;
19921 	INTBIG i;
19922 	CHAR line[20], *name;
19923 
19924 	DiaDimItem(dia, DTEV_EDITSTRINGS);
19925 	DiaSetText(dia, DTEV_VALUE, x_(""));
19926 	DiaNoEditControl(dia, DTEV_VALUE);
19927 	DiaDimItem(dia, DTEV_REMOVE);
19928 	DiaDimItem(dia, DTEV_COPY);
19929 	DiaSetText(dia, DTEV_TYPE, x_(""));
19930 	DiaSetText(dia, DTEV_DESCRIPTION, x_(""));
19931 	i = DiaGetCurLine(dia, DTEV_CURVARS);
19932 	if (i >= 0)
19933 	{
19934 		DiaUnDimItem(dia, DTEV_REMOVE);
19935 		name = DiaGetScrollLine(dia, DTEV_CURVARS, i);
19936 		for(i=0; us_knownvars[i].varname != 0; i++)
19937 			if (namesame(us_knownvars[i].varname, name) == 0) break;
19938 		if (us_knownvars[i].varname != 0)
19939 			DiaSetText(dia, DTEV_DESCRIPTION, us_knownvars[i].description);
19940 		for(t = newvars; t != NOTECHVAR; t = t->nexttechvar)
19941 			if (namesame(t->varname, name) == 0) break;
19942 		if (t != NOTECHVAR) switch (t->vartype&(VTYPE|VISARRAY))
19943 		{
19944 			case VINTEGER:
19945 				DiaSetText(dia, DTEV_TYPE, _("Integer"));
19946 				DiaEditControl(dia, DTEV_VALUE);
19947 				(void)esnprintf(line, 20, x_("%ld"), t->ival);
19948 				DiaSetText(dia, -DTEV_VALUE, line);
19949 				break;
19950 			case VFLOAT:
19951 				DiaSetText(dia, DTEV_TYPE, _("Real"));
19952 				DiaEditControl(dia, DTEV_VALUE);
19953 				(void)esnprintf(line, 20, x_("%g"), t->fval);
19954 				DiaSetText(dia, -DTEV_VALUE, line);
19955 				break;
19956 			case VSTRING:
19957 				DiaSetText(dia, DTEV_TYPE, _("String"));
19958 				DiaEditControl(dia, DTEV_VALUE);
19959 				DiaSetText(dia, -DTEV_VALUE, t->sval);
19960 				break;
19961 			case VSTRING|VISARRAY:
19962 				DiaSetText(dia, DTEV_TYPE, _("Strings"));
19963 				DiaUnDimItem(dia, DTEV_EDITSTRINGS);
19964 				break;
19965 		}
19966 	}
19967 
19968 	i = DiaGetCurLine(dia, DTEV_ALLVARS);
19969 	if (i >= 0)
19970 	{
19971 		name = DiaGetScrollLine(dia, DTEV_ALLVARS, i);
19972 		for(i=0; us_knownvars[i].varname != 0; i++)
19973 			if (namesame(us_knownvars[i].varname, name) == 0) break;
19974 		if (us_knownvars[i].varname != 0)
19975 		{
19976 			DiaSetText(dia, DTEV_DESCRIPTION, us_knownvars[i].description);
19977 			switch (us_knownvars[i].vartype&(VTYPE|VISARRAY))
19978 			{
19979 				case VINTEGER:         DiaSetText(dia, DTEV_TYPE, _("Integer"));   break;
19980 				case VFLOAT:           DiaSetText(dia, DTEV_TYPE, _("Real"));      break;
19981 				case VSTRING:          DiaSetText(dia, DTEV_TYPE, _("String"));    break;
19982 				case VSTRING|VISARRAY: DiaSetText(dia, DTEV_TYPE, _("Strings"));   break;
19983 			}
19984 		}
19985 		DiaUnDimItem(dia, DTEV_COPY);
19986 	}
19987 }
19988 
19989 /****************************** TECHNOLOGY SELECTION DIALOG ******************************/
19990 
19991 /* Technologies */
19992 static DIALOGITEM us_techselectdialogitems[] =
19993 {
19994  /*  1 */ {0, {96,216,120,280}, BUTTON, N_("OK")},
19995  /*  2 */ {0, {24,216,48,280}, BUTTON, N_("Cancel")},
19996  /*  3 */ {0, {8,8,153,193}, SCROLL, x_("")},
19997  /*  4 */ {0, {160,8,208,292}, MESSAGE, x_("")}
19998 };
19999 static DIALOG us_techselectdialog = {{50,75,267,376}, N_("Change Current Technology"), 0, 4, us_techselectdialogitems, 0, 0};
20000 
20001 /* special items for the "select technology" dialog: */
20002 #define DSLT_TECHLIST     3		/* Technology list (scroll) */
20003 #define DSLT_DESCRIPTION  4		/* Technology description (stat text) */
20004 
20005 /*
20006  * the meaning of "us_techlist":
20007  *  0  list all technologies without modification
20008  *  1  list all technologies, splitting "schematics" into "digital" and "analog"
20009  *  2  list all technologies that can be edited
20010  *  3  list all technologies that can be deleted
20011  */
20012 static INTBIG      us_techlist;
20013 static TECHNOLOGY *us_postechcomcomp;
20014 
20015 static void    us_stufftechdescript(void *dia);
20016 static BOOLEAN us_topoftechs(CHAR**);
20017 static CHAR   *us_nexttechs(void);
20018 
us_topoftechs(CHAR ** c)20019 BOOLEAN us_topoftechs(CHAR **c) { Q_UNUSED( c ); us_postechcomcomp = el_technologies; return(TRUE); }
20020 
us_nexttechs(void)20021 CHAR *us_nexttechs(void)
20022 {
20023 	REGISTER CHAR *retname;
20024 	REGISTER TECHNOLOGY *tech;
20025 
20026 	for(;;)
20027 	{
20028 		if (us_postechcomcomp == NOTECHNOLOGY)
20029 		{
20030 			us_postechcomcomp = 0;
20031 			if (us_techlist == 1) return(x_("schematic, analog"));
20032 		}
20033 		if (us_postechcomcomp == 0) return(0);
20034 
20035 		/* get the next technology in the list */
20036 		tech = us_postechcomcomp;
20037 		us_postechcomcomp = us_postechcomcomp->nexttechnology;
20038 
20039 		/* adjust the name if requested */
20040 		retname = tech->techname;
20041 		if (tech == sch_tech && us_techlist == 1)
20042 			retname = x_("schematic, digital");
20043 
20044 		/* ignore if requested */
20045 		if (us_techlist == 2 && (tech->userbits&NONSTANDARD) != 0) continue;
20046 		if (us_techlist == 3 && tech == gen_tech) continue;
20047 
20048 		/* accept */
20049 		break;
20050 	}
20051 	return(retname);
20052 }
20053 
us_stufftechdescript(void * dia)20054 void us_stufftechdescript(void *dia)
20055 {
20056 	REGISTER TECHNOLOGY *t;
20057 	REGISTER CHAR *tech;
20058 
20059 	tech = DiaGetScrollLine(dia, DSLT_TECHLIST, DiaGetCurLine(dia, DSLT_TECHLIST));
20060 	if (namesamen(tech, x_("schematic"), 9) == 0)
20061 	{
20062 		t = sch_tech;
20063 		DiaSetText(dia, DSLT_DESCRIPTION, t->techdescript);
20064 		return;
20065 	}
20066 
20067 	for(t = el_technologies; t != NOTECHNOLOGY; t = t->nexttechnology)
20068 		if (estrcmp(t->techname, tech) == 0) break;
20069 	if (t == NOTECHNOLOGY) return;
20070 	DiaSetText(dia, DSLT_DESCRIPTION, t->techdescript);
20071 }
20072 
us_technologydlog(CHAR * prompt,CHAR * paramstart[])20073 INTBIG us_technologydlog(CHAR *prompt, CHAR *paramstart[])
20074 {
20075 	REGISTER INTBIG itemHit, i, listlen;
20076 	REGISTER NODEPROTO *np;
20077 	REGISTER CHAR *defaulttech, *pt;
20078 	REGISTER void *dia;
20079 
20080 	/* display the new cell dialog box */
20081 	us_techselectdialog.movable = prompt;
20082 
20083 	/* the list of technologies depends on the nature of the operation */
20084 	us_techlist = 0;
20085 	defaulttech = x_("");
20086 	if (namesame(prompt, _("Change current technology")) == 0)
20087 	{
20088 		us_techlist = 1;
20089 		np = getcurcell();
20090 		if (np != NONODEPROTO)
20091 			defaulttech = us_techname(np);
20092 	} else if (namesame(prompt, _("Edit technology")) == 0)
20093 	{
20094 		us_techlist = 2;
20095 		defaulttech = el_curtech->techname;
20096 	} else if (namesame(prompt, _("Document technology")) == 0)
20097 	{
20098 		us_techlist = 0;
20099 		defaulttech = el_curtech->techname;
20100 	} else if (namesame(prompt, _("Convert to new technology")) == 0)
20101 	{
20102 		us_techlist = 0;
20103 	} else if (namesame(prompt, _("Delete technology")) == 0)
20104 	{
20105 		us_techlist = 3;
20106 	}
20107 
20108 	dia = DiaInitDialog(&us_techselectdialog);
20109 	if (dia == 0) return(0);
20110 	DiaInitTextDialog(dia, DSLT_TECHLIST, us_topoftechs, us_nexttechs, DiaNullDlogDone, 0,
20111 		SCSELMOUSE|SCSELKEY|SCDOUBLEQUIT|SCREPORT);
20112 	listlen = DiaGetNumScrollLines(dia, DSLT_TECHLIST);
20113 	for(i=0; i<listlen; i++)
20114 	{
20115 		pt = DiaGetScrollLine(dia, DSLT_TECHLIST, i);
20116 		if (estrcmp(pt, defaulttech) == 0)
20117 		{
20118 			DiaSelectLine(dia, DSLT_TECHLIST, i);
20119 			break;
20120 		}
20121 	}
20122 	us_stufftechdescript(dia);
20123 
20124 	/* loop until done */
20125 	for(;;)
20126 	{
20127 		itemHit = DiaNextHit(dia);
20128 		if (itemHit == CANCEL || itemHit == OK) break;
20129 		if (itemHit == DSLT_TECHLIST)
20130 		{
20131 			us_stufftechdescript(dia);
20132 			continue;
20133 		}
20134 	}
20135 
20136 	paramstart[0] = x_("");
20137 	if (itemHit != CANCEL)
20138 	{
20139 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
20140 		allocstring(&us_returneddialogstring, DiaGetScrollLine(dia, DSLT_TECHLIST,
20141 			DiaGetCurLine(dia, DSLT_TECHLIST)), us_tool->cluster);
20142 		paramstart[0] = us_returneddialogstring;
20143 	}
20144 	DiaDoneDialog(dia);
20145 	return(1);
20146 }
20147 
20148 /****************************** TECHNOLOGY OPTIONS DIALOG ******************************/
20149 
20150 /* Technology Options */
20151 static DIALOGITEM us_techsetdialogitems[] =
20152 {
20153  /*  1 */ {0, {240,328,264,392}, BUTTON, N_("OK")},
20154  /*  2 */ {0, {240,244,264,308}, BUTTON, N_("Cancel")},
20155  /*  3 */ {0, {32,20,48,156}, MESSAGE, N_("Metal layers:")},
20156  /*  4 */ {0, {32,164,48,312}, POPUP, x_("")},
20157  /*  5 */ {0, {216,20,232,156}, RADIO, N_("Full Geometry")},
20158  /*  6 */ {0, {216,164,232,300}, RADIO, N_("Stick Figures")},
20159  /*  7 */ {0, {88,320,104,424}, MESSAGE, N_("Artwork:")},
20160  /*  8 */ {0, {112,332,128,468}, CHECK, N_("Arrows filled")},
20161  /*  9 */ {0, {144,320,160,424}, MESSAGE, N_("Schematics:")},
20162  /* 10 */ {0, {168,332,184,492}, MESSAGE, N_("Negating Bubble Size")},
20163  /* 11 */ {0, {168,496,184,556}, EDITTEXT, x_("")},
20164  /* 12 */ {0, {8,8,24,192}, MESSAGE, N_("MOSIS CMOS:")},
20165  /* 13 */ {0, {136,320,137,624}, DIVIDELINE, x_("")},
20166  /* 14 */ {0, {4,316,228,317}, DIVIDELINE, x_("")},
20167  /* 15 */ {0, {144,20,160,260}, CHECK, N_("Disallow stacked vias")},
20168  /* 16 */ {0, {56,32,72,300}, RADIO, N_("SCMOS rules (4 metal or less)")},
20169  /* 17 */ {0, {76,32,92,300}, RADIO, N_("Submicron rules")},
20170  /* 18 */ {0, {96,32,112,300}, RADIO, N_("Deep rules (5 metal or more)")},
20171  /* 19 */ {0, {168,20,184,300}, CHECK, N_("Alternate Active and Poly contact rules")},
20172  /* 20 */ {0, {32,332,48,468}, MESSAGE, N_("Metal layers:")},
20173  /* 21 */ {0, {32,476,48,612}, POPUP, x_("")},
20174  /* 22 */ {0, {8,320,24,584}, MESSAGE, N_("MOSIS CMOS Submicron (old):")},
20175  /* 23 */ {0, {80,320,81,624}, DIVIDELINE, x_("")},
20176  /* 24 */ {0, {56,332,72,624}, CHECK, N_("Automatically convert to new MOSIS CMOS")},
20177  /* 25 */ {0, {120,20,136,300}, CHECK, N_("Second Polysilicon layer")},
20178  /* 26 */ {0, {192,332,208,624}, MESSAGE, N_("Use Lambda values from this Technology:")},
20179  /* 27 */ {0, {212,388,228,552}, POPUP, x_("")},
20180  /* 28 */ {0, {192,20,208,300}, CHECK, N_("Show Special transistors")}
20181 };
20182 static DIALOG us_techsetdialog = {{75,75,348,708}, N_("Technology Options"), 0, 28, us_techsetdialogitems, 0, 0};
20183 
20184 /* special items for the "Technology Options" dialog: */
20185 #define DTHO_MOCMOS_METALS       4		/* MOCMOS metal layers (popup) */
20186 #define DTHO_MOCMOS_FULLGEOM     5		/* MOCMOS full-geometry (radio) */
20187 #define DTHO_MOCMOS_STICKS       6		/* MOCMOS stick-figure (radio) */
20188 #define DTHO_ARTWORK_ARROWS      8		/* ARTWORK filled arrow (check) */
20189 #define DTHO_SCHEM_BUBBLESIZE   11		/* SCHEMATICS invert bubble (edit text) */
20190 #define DTHO_MOCMOS_STACKVIA    15		/* MOCMOS stacked vias (check) */
20191 #define DTHO_MOCMOS_SCMOS       16		/* MOCMOS SCMOS rules (radio) */
20192 #define DTHO_MOCMOS_SUBM        17		/* MOCMOS submicron rules (radio) */
20193 #define DTHO_MOCMOS_DEEP        18		/* MOCMOS deep rules (radio) */
20194 #define DTHO_MOCMOS_ALTCONT     19		/* MOCMOS alternate act/poly (check) */
20195 #define DTHO_MOCMOSSUB_METALS   21		/* MOCMOSSUB metal layers (popup) */
20196 #define DTHO_MOCMOSSUB_CONVERT  24		/* MOCMOSSUB convert technology (check) */
20197 #define DTHO_MOCMOS_TWOPOLY     25		/* MOCMOS second polysilicon layer (check) */
20198 #define DTHO_SCHEM_LAMBDATECH   27		/* SCHEMATICS tech to use for lambda (popup) */
20199 #define DTHO_MOCMOS_SPECTRAN    28		/* MOCMOS use special transistors (check) */
20200 
us_techoptdlog(void)20201 INTBIG us_techoptdlog(void)
20202 {
20203 	REGISTER INTBIG itemHit, which, i, mocmosbits, mocmossubbits, artbits,
20204 		origmocmosbits, origmocmossubbits, origartbits, schbubblesize, origschbubblesize,
20205 		*oldnodewidthoffset, len;
20206 	REGISTER INTBIG techcount;
20207 	REGISTER VARIABLE *var;
20208 	REGISTER TECHNOLOGY *inischemtech, *tech;
20209 	WINDOWPART *w;
20210 	CHAR *newlang[5], **techlist;
20211 	static CHAR *metalcount[] = {N_("2 Layers"), N_("3 Layers"), N_("4 Layers"),
20212 		N_("5 Layers"), N_("6 Layers")};
20213 	CHAR *par[2];
20214 	REGISTER void *dia;
20215 
20216 	/* display the options dialog box */
20217 	dia = DiaInitDialog(&us_techsetdialog);
20218 	if (dia == 0) return(0);
20219 	for(i=0; i<5; i++) newlang[i] = TRANSLATE(metalcount[i]);
20220 	DiaSetPopup(dia, DTHO_MOCMOS_METALS, 5, newlang);
20221 	DiaSetPopup(dia, DTHO_MOCMOSSUB_METALS, 5, newlang);
20222 
20223 	/* get state of "mocmossub" technology */
20224 	origmocmossubbits = mocmossubbits = asktech(mocmossub_tech, x_("get-state"));
20225 	switch (mocmossubbits&MOCMOSSUBMETALS)
20226 	{
20227 		case MOCMOSSUB2METAL: DiaSetPopupEntry(dia, DTHO_MOCMOSSUB_METALS, 0);   break;
20228 		case MOCMOSSUB3METAL: DiaSetPopupEntry(dia, DTHO_MOCMOSSUB_METALS, 1);   break;
20229 		case MOCMOSSUB4METAL: DiaSetPopupEntry(dia, DTHO_MOCMOSSUB_METALS, 2);   break;
20230 		case MOCMOSSUB5METAL: DiaSetPopupEntry(dia, DTHO_MOCMOSSUB_METALS, 3);   break;
20231 		case MOCMOSSUB6METAL: DiaSetPopupEntry(dia, DTHO_MOCMOSSUB_METALS, 4);   break;
20232 	}
20233 	if ((mocmossubbits&MOCMOSSUBNOCONV) == 0) DiaSetControl(dia, DTHO_MOCMOSSUB_CONVERT, 1);
20234 
20235 	/* get state of "mocmos" technology */
20236 	origmocmosbits = mocmosbits = asktech(mocmos_tech, x_("get-state"));
20237 	DiaUnDimItem(dia, DTHO_MOCMOS_DEEP);
20238 	DiaUnDimItem(dia, DTHO_MOCMOS_SCMOS);
20239 	DiaUnDimItem(dia, DTHO_MOCMOS_TWOPOLY);
20240 	switch (mocmosbits&MOCMOSMETALS)
20241 	{
20242 		case MOCMOS2METAL:
20243 			DiaSetPopupEntry(dia, DTHO_MOCMOS_METALS, 0);
20244 			DiaDimItem(dia, DTHO_MOCMOS_DEEP);
20245 			break;
20246 		case MOCMOS3METAL:
20247 			DiaSetPopupEntry(dia, DTHO_MOCMOS_METALS, 1);
20248 			DiaDimItem(dia, DTHO_MOCMOS_DEEP);
20249 			break;
20250 		case MOCMOS4METAL:
20251 			DiaSetPopupEntry(dia, DTHO_MOCMOS_METALS, 2);
20252 			DiaDimItem(dia, DTHO_MOCMOS_DEEP);
20253 			break;
20254 		case MOCMOS5METAL:
20255 			DiaSetPopupEntry(dia, DTHO_MOCMOS_METALS, 3);
20256 			DiaDimItem(dia, DTHO_MOCMOS_SCMOS);
20257 			break;
20258 		case MOCMOS6METAL:
20259 			DiaSetPopupEntry(dia, DTHO_MOCMOS_METALS, 4);
20260 			DiaDimItem(dia, DTHO_MOCMOS_SCMOS);
20261 			break;
20262 	}
20263 	if ((mocmosbits&MOCMOSNOSTACKEDVIAS) != 0) DiaSetControl(dia, DTHO_MOCMOS_STACKVIA, 1);
20264 	if ((mocmosbits&MOCMOSALTAPRULES) != 0) DiaSetControl(dia, DTHO_MOCMOS_ALTCONT, 1);
20265 	if ((mocmosbits&MOCMOSTWOPOLY) != 0) DiaSetControl(dia, DTHO_MOCMOS_TWOPOLY, 1);
20266 	if ((mocmosbits&MOCMOSSPECIALTRAN) != 0) DiaSetControl(dia, DTHO_MOCMOS_SPECTRAN, 1);
20267 	switch (mocmosbits&MOCMOSRULESET)
20268 	{
20269 		case MOCMOSSCMOSRULES:
20270 			DiaSetControl(dia, DTHO_MOCMOS_SCMOS, 1);
20271 			break;
20272 		case MOCMOSSUBMRULES:
20273 			DiaSetControl(dia, DTHO_MOCMOS_SUBM, 1);
20274 			break;
20275 		case MOCMOSDEEPRULES:
20276 			DiaSetControl(dia, DTHO_MOCMOS_DEEP, 1);
20277 			DiaDimItem(dia, DTHO_MOCMOS_TWOPOLY);
20278 			break;
20279 	}
20280 	if ((mocmosbits&MOCMOSSTICKFIGURE) != 0) DiaSetControl(dia, DTHO_MOCMOS_STICKS, 1); else
20281 		DiaSetControl(dia, DTHO_MOCMOS_FULLGEOM, 1);
20282 
20283 	/* cache "mocmos" node sizes in case they change and so must layout */
20284 	oldnodewidthoffset = 0;
20285 	var = getval((INTBIG)mocmos_tech, VTECHNOLOGY, VFRACT|VISARRAY, x_("TECH_node_width_offset"));
20286 	if (var != NOVARIABLE)
20287 	{
20288 		len = getlength(var);
20289 		oldnodewidthoffset = (INTBIG *)emalloc(len * SIZEOFINTBIG, el_tempcluster);
20290 		if (oldnodewidthoffset == 0) return(1);
20291 		for(i=0; i<len; i++)
20292 			oldnodewidthoffset[i] = ((INTBIG *)var->addr)[i];
20293 	}
20294 
20295 	/* get state of "artwork" technology */
20296 	origartbits = artbits = asktech(art_tech, x_("get-state"));
20297 	if ((artbits&ARTWORKFILLARROWHEADS) != 0) DiaSetControl(dia, DTHO_ARTWORK_ARROWS, 1);
20298 
20299 	/* get state of "schematic" technology */
20300 	origschbubblesize = schbubblesize = asktech(sch_tech, x_("get-bubble-size"));
20301 	DiaSetText(dia, DTHO_SCHEM_BUBBLESIZE, frtoa(schbubblesize));
20302 	techcount = 0;
20303 	for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
20304 	{
20305 		if ((tech->userbits&(NONELECTRICAL|NOPRIMTECHNOLOGY)) != 0) continue;
20306 		if (tech == sch_tech || tech == gen_tech) continue;
20307 		techcount++;
20308 	}
20309 	techlist = (CHAR **)emalloc(techcount * (sizeof (CHAR *)), el_tempcluster);
20310 	if (techlist == 0) return(1);
20311 	techcount = 0;
20312 	for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
20313 	{
20314 		if ((tech->userbits&(NONELECTRICAL|NOPRIMTECHNOLOGY)) != 0) continue;
20315 		if (tech == sch_tech || tech == gen_tech) continue;
20316 		techlist[techcount] = tech->techname;
20317 		tech->temp1 = techcount;
20318 		techcount++;
20319 	}
20320 	DiaSetPopup(dia, DTHO_SCHEM_LAMBDATECH, techcount, techlist);
20321 	inischemtech = defschematictechnology(el_curtech);
20322 	if (inischemtech != NOTECHNOLOGY)
20323 		DiaSetPopupEntry(dia, DTHO_SCHEM_LAMBDATECH, inischemtech->temp1);
20324 
20325 	/* loop until done */
20326 	for(;;)
20327 	{
20328 		itemHit = DiaNextHit(dia);
20329 		if (itemHit == OK || itemHit == CANCEL) break;
20330 		if (itemHit == DTHO_MOCMOS_METALS)
20331 		{
20332 			i = DiaGetPopupEntry(dia, DTHO_MOCMOS_METALS);
20333 			if (i <= 2)
20334 			{
20335 				/* 4 metal layers or less */
20336 				if (DiaGetControl(dia, DTHO_MOCMOS_DEEP) != 0)
20337 				{
20338 					DiaSetControl(dia, DTHO_MOCMOS_DEEP, 0);
20339 					DiaSetControl(dia, DTHO_MOCMOS_SUBM, 1);
20340 				}
20341 				DiaUnDimItem(dia, DTHO_MOCMOS_SCMOS);
20342 				DiaDimItem(dia, DTHO_MOCMOS_DEEP);
20343 			} else
20344 			{
20345 				/* 5 metal layers or more */
20346 				if (DiaGetControl(dia, DTHO_MOCMOS_SCMOS) != 0)
20347 				{
20348 					DiaSetControl(dia, DTHO_MOCMOS_SCMOS, 0);
20349 					DiaSetControl(dia, DTHO_MOCMOS_SUBM, 1);
20350 				}
20351 				DiaDimItem(dia, DTHO_MOCMOS_SCMOS);
20352 				DiaUnDimItem(dia, DTHO_MOCMOS_DEEP);
20353 			}
20354 			continue;
20355 		}
20356 		if (itemHit == DTHO_MOCMOS_SCMOS || itemHit == DTHO_MOCMOS_SUBM ||
20357 			itemHit == DTHO_MOCMOS_DEEP)
20358 		{
20359 			DiaSetControl(dia, DTHO_MOCMOS_SCMOS, 0);
20360 			DiaSetControl(dia, DTHO_MOCMOS_SUBM, 0);
20361 			DiaSetControl(dia, DTHO_MOCMOS_DEEP, 0);
20362 			DiaSetControl(dia, itemHit, 1);
20363 			if (itemHit == DTHO_MOCMOS_DEEP)
20364 			{
20365 				DiaSetControl(dia, DTHO_MOCMOS_TWOPOLY, 0);
20366 				DiaDimItem(dia, DTHO_MOCMOS_TWOPOLY);
20367 			} else
20368 			{
20369 				DiaUnDimItem(dia, DTHO_MOCMOS_TWOPOLY);
20370 			}
20371 			continue;
20372 		}
20373 		if (itemHit == DTHO_MOCMOS_FULLGEOM || itemHit == DTHO_MOCMOS_STICKS)
20374 		{
20375 			DiaSetControl(dia, DTHO_MOCMOS_FULLGEOM, 0);
20376 			DiaSetControl(dia, DTHO_MOCMOS_STICKS, 0);
20377 			DiaSetControl(dia, itemHit, 1);
20378 			continue;
20379 		}
20380 		if (itemHit == DTHO_ARTWORK_ARROWS || itemHit == DTHO_MOCMOS_STACKVIA ||
20381 			itemHit == DTHO_MOCMOS_SCMOS || itemHit == DTHO_MOCMOS_ALTCONT ||
20382 			itemHit == DTHO_MOCMOSSUB_CONVERT || itemHit == DTHO_MOCMOS_TWOPOLY ||
20383 			itemHit == DTHO_MOCMOS_SPECTRAN)
20384 		{
20385 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
20386 			continue;
20387 		}
20388 	}
20389 
20390 	if (itemHit == OK)
20391 	{
20392 		/* update "mocmossub" technology */
20393 		which = DiaGetPopupEntry(dia, DTHO_MOCMOSSUB_METALS);
20394 		mocmossubbits &= ~MOCMOSSUBMETALS;
20395 		switch (which)
20396 		{
20397 			case 0: mocmossubbits |= MOCMOSSUB2METAL;   break;
20398 			case 1: mocmossubbits |= MOCMOSSUB3METAL;   break;
20399 			case 2: mocmossubbits |= MOCMOSSUB4METAL;   break;
20400 			case 3: mocmossubbits |= MOCMOSSUB5METAL;   break;
20401 			case 4: mocmossubbits |= MOCMOSSUB6METAL;   break;
20402 		}
20403 		if (DiaGetControl(dia, DTHO_MOCMOSSUB_CONVERT) == 0) mocmossubbits |= MOCMOSSUBNOCONV; else
20404 			mocmossubbits &= ~MOCMOSSUBNOCONV;
20405 		if (origmocmossubbits != mocmossubbits)
20406 		{
20407 			setvalkey((INTBIG)mocmossub_tech, VTECHNOLOGY, el_techstate_key, mocmossubbits, VINTEGER);
20408 			if (el_curtech == mocmossub_tech)
20409 			{
20410 				par[0] = x_("size");
20411 				par[1] = x_("auto");
20412 				us_menu(2, par);
20413 				us_setmenunodearcs();
20414 			}
20415 		}
20416 
20417 		/* update "mocmos" technology */
20418 		which = DiaGetPopupEntry(dia, DTHO_MOCMOS_METALS);
20419 		mocmosbits &= ~MOCMOSMETALS;
20420 		switch (which)
20421 		{
20422 			case 0: mocmosbits |= MOCMOS2METAL;   break;
20423 			case 1: mocmosbits |= MOCMOS3METAL;   break;
20424 			case 2: mocmosbits |= MOCMOS4METAL;   break;
20425 			case 3: mocmosbits |= MOCMOS5METAL;   break;
20426 			case 4: mocmosbits |= MOCMOS6METAL;   break;
20427 		}
20428 		if (DiaGetControl(dia, DTHO_MOCMOS_STICKS) != 0) mocmosbits |= MOCMOSSTICKFIGURE; else
20429 			mocmosbits &= ~MOCMOSSTICKFIGURE;
20430 		if (DiaGetControl(dia, DTHO_MOCMOS_STACKVIA) != 0) mocmosbits |= MOCMOSNOSTACKEDVIAS; else
20431 			mocmosbits &= ~MOCMOSNOSTACKEDVIAS;
20432 		if (DiaGetControl(dia, DTHO_MOCMOS_ALTCONT) != 0) mocmosbits |= MOCMOSALTAPRULES; else
20433 			mocmosbits &= ~MOCMOSALTAPRULES;
20434 		if (DiaGetControl(dia, DTHO_MOCMOS_TWOPOLY) != 0) mocmosbits |= MOCMOSTWOPOLY; else
20435 			mocmosbits &= ~MOCMOSTWOPOLY;
20436 		if (DiaGetControl(dia, DTHO_MOCMOS_SPECTRAN) != 0) mocmosbits |= MOCMOSSPECIALTRAN; else
20437 			mocmosbits &= ~MOCMOSSPECIALTRAN;
20438 		mocmosbits &= ~MOCMOSRULESET;
20439 		if (DiaGetControl(dia, DTHO_MOCMOS_SCMOS) != 0) mocmosbits |= MOCMOSSCMOSRULES; else
20440 			if (DiaGetControl(dia, DTHO_MOCMOS_SUBM) != 0) mocmosbits |= MOCMOSSUBMRULES; else
20441 				if (DiaGetControl(dia, DTHO_MOCMOS_DEEP) != 0) mocmosbits |= MOCMOSDEEPRULES;
20442 		if (origmocmosbits != mocmosbits)
20443 		{
20444 			setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, el_techstate_key, mocmosbits, VINTEGER);
20445 			if ((origmocmosbits&MOCMOSSTICKFIGURE) != (mocmosbits&MOCMOSSTICKFIGURE))
20446 				us_figuretechopaque(mocmos_tech);
20447 			if (el_curtech == mocmos_tech)
20448 			{
20449 				par[0] = x_("size");
20450 				par[1] = x_("auto");
20451 				us_menu(2, par);
20452 			}
20453 		}
20454 
20455 		/* see if change to "mocmos" options causes node sizes to change */
20456 		if (oldnodewidthoffset != 0)
20457 		{
20458 			REGISTER INTBIG lambda, *newnodewidthoffset, index, dlx, dhx, dly, dhy;
20459 			REGISTER NODEINST *ni;
20460 			INTBIG sx, sy;
20461 			REGISTER NODEPROTO *np;
20462 			REGISTER LIBRARY *lib;
20463 
20464 			var = getval((INTBIG)mocmos_tech, VTECHNOLOGY, VFRACT|VISARRAY, x_("TECH_node_width_offset"));
20465 			if (var != NOVARIABLE)
20466 			{
20467 				len = getlength(var);
20468 				newnodewidthoffset = (INTBIG *)var->addr;
20469 				for(i=0; i<len; i++)
20470 					if (oldnodewidthoffset[i] != newnodewidthoffset[i]) break;
20471 				if (i < len)
20472 				{
20473 					/* node sizes changed */
20474 					for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
20475 					{
20476 						for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
20477 						{
20478 							for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20479 							{
20480 								if (ni->proto->primindex == 0) continue;
20481 								if (ni->proto->tech != mocmos_tech) continue;
20482 								/* ignore if default size */
20483 								defaultnodesize(ni->proto, &sx, &sy);
20484 								if (sx == ni->highx - ni->lowx &&
20485 									sy == ni->highy - ni->lowy) continue;
20486 								index = (ni->proto->primindex - 1) * 4;
20487 								if (oldnodewidthoffset[index] == newnodewidthoffset[index] &&
20488 									oldnodewidthoffset[index+1] == newnodewidthoffset[index+1] &&
20489 									oldnodewidthoffset[index+2] == newnodewidthoffset[index+2] &&
20490 									oldnodewidthoffset[index+3] == newnodewidthoffset[index+3])
20491 										continue;
20492 								lambda = lib->lambda[mocmos_tech->techindex];
20493 								dlx = (newnodewidthoffset[index] - oldnodewidthoffset[index]) * lambda / WHOLE;
20494 								dhx = (newnodewidthoffset[index+1] - oldnodewidthoffset[index+1]) * lambda / WHOLE;
20495 								dly = (newnodewidthoffset[index+2] - oldnodewidthoffset[index+2]) * lambda / WHOLE;
20496 								dhy = (newnodewidthoffset[index+3] - oldnodewidthoffset[index+3]) * lambda / WHOLE;
20497 								drcminnodesize(ni->proto, lib, &sx, &sy, 0);
20498 
20499 								/* only scale an axis if it is larger than default */
20500 								if (ni->highx - ni->lowx <= sx) dlx = dhx = 0;
20501 								if (ni->highy - ni->lowy <= sy) dly = dhy = 0;
20502 
20503 								startobjectchange((INTBIG)ni, VNODEINST);
20504 								modifynodeinst(ni, -dlx, -dly, dhx, dhy, 0, 0);
20505 								endobjectchange((INTBIG)ni, VNODEINST);
20506 							}
20507 						}
20508 					}
20509 				}
20510 			}
20511 			efree((CHAR *)oldnodewidthoffset);
20512 		}
20513 
20514 		/* update "artwork" technology */
20515 		if (DiaGetControl(dia, DTHO_ARTWORK_ARROWS) != 0) artbits |= ARTWORKFILLARROWHEADS; else
20516 			artbits &= ~ARTWORKFILLARROWHEADS;
20517 		if (artbits != origartbits)
20518 		{
20519 			setvalkey((INTBIG)art_tech, VTECHNOLOGY, el_techstate_key, artbits, VINTEGER);
20520 			if (el_curtech == art_tech)
20521 				us_drawmenu(0, NOWINDOWFRAME);
20522 		}
20523 
20524 		/* update "schematic" technology */
20525 		schbubblesize = atofr(DiaGetText(dia, DTHO_SCHEM_BUBBLESIZE));
20526 		if (schbubblesize != origschbubblesize)
20527 			(void)asktech(sch_tech, x_("set-bubble-size"), schbubblesize);
20528 		i = DiaGetPopupEntry(dia, DTHO_SCHEM_LAMBDATECH);
20529 		for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
20530 			if (namesame(tech->techname, techlist[i]) == 0) break;
20531 		if (tech != NOTECHNOLOGY && tech == inischemtech) tech = NOTECHNOLOGY;
20532 		if (tech != NOTECHNOLOGY)
20533 			setval((INTBIG)sch_tech, VTECHNOLOGY, x_("TECH_layout_technology"),
20534 				(INTBIG)tech->techname, VSTRING);
20535 		efree((CHAR *)techlist);
20536 
20537 		/* redisplay all windows if anything changed */
20538 		if (origmocmosbits != mocmosbits || origmocmossubbits != mocmossubbits ||
20539 			origartbits != artbits || origschbubblesize != schbubblesize)
20540 		{
20541 			us_pushhighlight();
20542 			us_clearhighlightcount();
20543 			for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
20544 				if (w->redisphandler != 0) (*w->redisphandler)(w);
20545 			us_pophighlight(FALSE);
20546 		}
20547 	}
20548 	DiaDoneDialog(dia);
20549 	return(0);
20550 }
20551 
20552 /****************************** TEXT MODIFICATION DIALOG ******************************/
20553 
20554 /* Text: Modify */
20555 static DIALOGITEM us_txtmodsizedialogitems[] =
20556 {
20557  /*  1 */ {0, {200,376,224,456}, BUTTON, N_("OK")},
20558  /*  2 */ {0, {160,376,184,456}, BUTTON, N_("Cancel")},
20559  /*  3 */ {0, {156,180,172,340}, RADIO, N_("Points (max 63)")},
20560  /*  4 */ {0, {156,124,172,172}, EDITTEXT, x_("")},
20561  /*  5 */ {0, {8,8,24,256}, CHECK, N_("Change size of node text")},
20562  /*  6 */ {0, {28,8,44,260}, CHECK, N_("Change size of arc text")},
20563  /*  7 */ {0, {48,8,64,260}, CHECK, N_("Change size of export text")},
20564  /*  8 */ {0, {88,8,104,260}, CHECK, N_("Change size of instance name text")},
20565  /*  9 */ {0, {68,8,84,260}, CHECK, N_("Change size of nonlayout text")},
20566  /* 10 */ {0, {16,264,32,476}, RADIO, N_("Change only selected objects")},
20567  /* 11 */ {0, {36,264,52,476}, RADIO, N_("Change all in this cell")},
20568  /* 12 */ {0, {96,264,112,476}, RADIO, N_("Change all in this library")},
20569  /* 13 */ {0, {180,180,196,340}, RADIO, N_("Lambda (max 127.75)")},
20570  /* 14 */ {0, {180,124,196,172}, EDITTEXT, x_("")},
20571  /* 15 */ {0, {204,68,220,152}, MESSAGE, N_("Text font:")},
20572  /* 16 */ {0, {204,156,220,336}, POPUP, x_("")},
20573  /* 17 */ {0, {228,68,244,140}, CHECK, N_("Italic")},
20574  /* 18 */ {0, {228,168,244,232}, CHECK, N_("Bold")},
20575  /* 19 */ {0, {228,256,244,336}, CHECK, N_("Underline")},
20576  /* 20 */ {0, {168,68,184,116}, MESSAGE, N_("Size")},
20577  /* 21 */ {0, {108,8,124,260}, CHECK, N_("Change size of cell text")},
20578  /* 22 */ {0, {56,264,72,476}, RADIO, N_("Change all cells with view:")},
20579  /* 23 */ {0, {76,304,92,476}, POPUP, x_("")},
20580  /* 24 */ {0, {132,8,148,476}, MESSAGE, x_("")}
20581 };
20582 static DIALOG us_txtmodsizedialog = {{75,75,328,561}, N_("Change Text Size"), 0, 24, us_txtmodsizedialogitems, 0, 0};
20583 
20584 static void us_settextsize(HIGHLIGHT *high, UINTBIG *descript, INTBIG changenode, INTBIG changearc,
20585 	INTBIG changeexport, INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell);
20586 static void us_includetextsize(INTBIG size, INTBIG *lowabs, INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel);
20587 static void us_gathertextsize(HIGHLIGHT *high, INTBIG changenode, INTBIG changearc, INTBIG changeexport,
20588 	INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell,
20589 	INTBIG *lowabs, INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel);
20590 static void us_setcurtextsizes(void *dia, INTBIG changenode, INTBIG changearc, INTBIG changeexport,
20591 	INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell, INTBIG *lowabs,
20592 	INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel, CHAR **viewlist);
20593 
20594 /* special items for "modify text size" dialog: */
20595 #define DMTX_ABSTEXTSIZE_L   3		/* Absolute text size label (radio) */
20596 #define DMTX_ABSTEXTSIZE     4		/* Absolute text size (edit text) */
20597 #define DMTX_NODES           5		/* change node text (check) */
20598 #define DMTX_ARCS            6		/* change arc text (check) */
20599 #define DMTX_EXPORTS         7		/* change export text (check) */
20600 #define DMTX_INSTANCES       8		/* change instance name text (check) */
20601 #define DMTX_NONLAYOUTS      9		/* change nonlayout text (check) */
20602 #define DMTX_SELECTED       10		/* change selected (radio) */
20603 #define DMTX_ALLINCELL      11		/* change all in cell (radio) */
20604 #define DMTX_ALLINLIB       12		/* change all in library (radio) */
20605 #define DMTX_RELTEXTSIZE_L  13		/* Relative text size label (radio) */
20606 #define DMTX_RELTEXTSIZE    14		/* Relative text size (edit text) */
20607 #define DMTX_TEXTFACE       16		/* Text face (popup) */
20608 #define DMTX_TEXTFACE_L     15		/* Text face label (stat text) */
20609 #define DMTX_TEXTITALIC     17		/* Text italic (check) */
20610 #define DMTX_TEXTBOLD       18		/* Text bold (check) */
20611 #define DMTX_TEXTUNDERLINE  19		/* Text underline (check) */
20612 #define DMTX_CELL           21		/* change cell text (check) */
20613 #define DMTX_ALLWITHVIEW    22		/* change all cells with view (radio) */
20614 #define DMTX_WHICHVIEW      23		/* view to select (popup) */
20615 #define DMTX_CURSIZE        24		/* current text sizes (stat text) */
20616 
us_modtextsizedlog(void)20617 INTBIG us_modtextsizedlog(void)
20618 {
20619 	INTBIG itemHit, i, len, changenode, changearc, changeexport, changenonlayout,
20620 		changeinstance, changecell, viewcount, lowabs, highabs, lowrel, highrel;
20621 	UINTBIG newdescript[TEXTDESCRIPTSIZE];
20622 	REGISTER VARIABLE *var;
20623 	REGISTER NODEPROTO *np, *cell;
20624 	REGISTER BOOLEAN updaterange;
20625 	REGISTER WINDOWPART *win;
20626 	REGISTER NODEINST *ni;
20627 	REGISTER ARCINST *ai;
20628 	REGISTER VIEW *v;
20629 	HIGHLIGHT high;
20630 	CHAR **viewlist;
20631 	REGISTER void *dia, *infstr;
20632 
20633 	/* display the modify text size dialog box */
20634 	dia = DiaInitDialog(&us_txtmodsizedialog);
20635 	if (dia == 0) return(0);
20636 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
20637 	cell = getcurcell();
20638 
20639 	/* load the list of views */
20640 	viewcount = us_makeviewlist(&viewlist);
20641 	DiaSetPopup(dia, DMTX_WHICHVIEW, viewcount, viewlist);
20642 
20643 	/* set the text size popups */
20644 	if (var == NOVARIABLE) DiaDimItem(dia, DMTX_SELECTED); else
20645 		DiaUnDimItem(dia, DMTX_SELECTED);
20646 	if (cell == NONODEPROTO) DiaDimItem(dia, DMTX_ALLINCELL); else
20647 		DiaUnDimItem(dia, DMTX_ALLINCELL);
20648 	if (var != NOVARIABLE)
20649 	{
20650 		DiaSetControl(dia, DMTX_SELECTED, 1);
20651 	} else if (cell != NONODEPROTO)
20652 	{
20653 		DiaSetControl(dia, DMTX_ALLINCELL, 1);
20654 	} else
20655 	{
20656 		DiaSetControl(dia, DMTX_ALLINLIB, 1);
20657 	}
20658 	if (graphicshas(CANCHOOSEFACES))
20659 	{
20660 		DiaUnDimItem(dia, DMTX_TEXTFACE_L);
20661 		us_setpopupface(DMTX_TEXTFACE, 0, TRUE, dia);
20662 	} else
20663 	{
20664 		DiaDimItem(dia, DMTX_TEXTFACE_L);
20665 	}
20666 	if (graphicshas(CANMODIFYFONTS))
20667 	{
20668 		DiaUnDimItem(dia, DMTX_TEXTITALIC);
20669 		DiaUnDimItem(dia, DMTX_TEXTBOLD);
20670 		DiaUnDimItem(dia, DMTX_TEXTUNDERLINE);
20671 	} else
20672 	{
20673 		DiaDimItem(dia, DMTX_TEXTITALIC);
20674 		DiaDimItem(dia, DMTX_TEXTBOLD);
20675 		DiaDimItem(dia, DMTX_TEXTUNDERLINE);
20676 	}
20677 	DiaSetControl(dia, DMTX_RELTEXTSIZE_L, 1);
20678 	DiaSetText(dia, DMTX_RELTEXTSIZE, x_("1"));
20679 	updaterange = TRUE;
20680 	for(;;)
20681 	{
20682 		if (updaterange)
20683 		{
20684 			changenode = DiaGetControl(dia, DMTX_NODES);
20685 			changearc = DiaGetControl(dia, DMTX_ARCS);
20686 			changeexport = DiaGetControl(dia, DMTX_EXPORTS);
20687 			changenonlayout = DiaGetControl(dia, DMTX_NONLAYOUTS);
20688 			changeinstance = DiaGetControl(dia, DMTX_INSTANCES);
20689 			changecell = DiaGetControl(dia, DMTX_CELL);
20690 			us_setcurtextsizes(dia, changenode, changearc, changeexport, changenonlayout,
20691 				changeinstance, changecell, &lowabs, &highabs, &lowrel, &highrel, viewlist);
20692 			infstr = initinfstr();
20693 			if (lowabs > highabs && lowrel > highrel)
20694 			{
20695 				addstringtoinfstr(infstr, _("No text to change"));
20696 			} else
20697 			{
20698 				addstringtoinfstr(infstr, _("Text runs from"));
20699 				if (lowabs <= highabs)
20700 				{
20701 					formatinfstr(infstr, x_(" %ld to %ld points"), lowabs, highabs);
20702 					if (lowrel <= highrel) addtoinfstr(infstr, ';');
20703 				}
20704 				if (lowrel <= highrel)
20705 					formatinfstr(infstr, x_(" %s to %s lambda"),
20706 						frtoa(lowrel * WHOLE / 4), frtoa(highrel * WHOLE / 4));
20707 			}
20708 			DiaSetText(dia, DMTX_CURSIZE, returninfstr(infstr));
20709 			updaterange = FALSE;
20710 		}
20711 		itemHit = DiaNextHit(dia);
20712 		if (itemHit == OK || itemHit == CANCEL) break;
20713 		if (itemHit == DMTX_SELECTED || itemHit == DMTX_ALLINCELL ||
20714 			itemHit == DMTX_ALLINLIB || itemHit == DMTX_ALLWITHVIEW)
20715 		{
20716 			DiaSetControl(dia, DMTX_SELECTED, 0);
20717 			DiaSetControl(dia, DMTX_ALLINCELL, 0);
20718 			DiaSetControl(dia, DMTX_ALLINLIB, 0);
20719 			DiaSetControl(dia, DMTX_ALLWITHVIEW, 0);
20720 			DiaSetControl(dia, itemHit, 1);
20721 			updaterange = TRUE;
20722 			continue;
20723 		}
20724 		if (itemHit == DMTX_NODES || itemHit == DMTX_ARCS ||
20725 			itemHit == DMTX_EXPORTS || itemHit == DMTX_NONLAYOUTS ||
20726 			itemHit == DMTX_INSTANCES || itemHit == DMTX_CELL)
20727 		{
20728 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
20729 			updaterange = TRUE;
20730 			continue;
20731 		}
20732 		if (itemHit == DMTX_RELTEXTSIZE) itemHit = DMTX_RELTEXTSIZE_L;
20733 		if (itemHit == DMTX_ABSTEXTSIZE) itemHit = DMTX_ABSTEXTSIZE_L;
20734 		if (itemHit == DMTX_RELTEXTSIZE_L || itemHit == DMTX_ABSTEXTSIZE_L)
20735 		{
20736 			DiaSetControl(dia, DMTX_RELTEXTSIZE_L, 0);
20737 			DiaSetControl(dia, DMTX_ABSTEXTSIZE_L, 0);
20738 			DiaSetControl(dia, itemHit, 1);
20739 			continue;
20740 		}
20741 		if (itemHit == DMTX_TEXTITALIC || itemHit == DMTX_TEXTBOLD ||
20742 			itemHit == DMTX_TEXTUNDERLINE)
20743 		{
20744 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
20745 			continue;
20746 		}
20747 	}
20748 	if (itemHit == OK)
20749 	{
20750 		changenode = DiaGetControl(dia, DMTX_NODES);
20751 		changearc = DiaGetControl(dia, DMTX_ARCS);
20752 		changeexport = DiaGetControl(dia, DMTX_EXPORTS);
20753 		changenonlayout = DiaGetControl(dia, DMTX_NONLAYOUTS);
20754 		changeinstance = DiaGetControl(dia, DMTX_INSTANCES);
20755 		changecell = DiaGetControl(dia, DMTX_CELL);
20756 
20757 		/* determine text descriptor */
20758 		TDCLEAR(newdescript);
20759 		if (DiaGetControl(dia, DMTX_ABSTEXTSIZE_L) != 0)
20760 		{
20761 			i = eatoi(DiaGetText(dia, DMTX_ABSTEXTSIZE));
20762 			if (i <= 0) i = 4;
20763 			if (i >= TXTMAXPOINTS) i = TXTMAXPOINTS;
20764 			TDSETSIZE(newdescript, TXTSETPOINTS(i));
20765 		} else
20766 		{
20767 			i = atofr(DiaGetText(dia, DMTX_RELTEXTSIZE)) * 4 / WHOLE;
20768 			if (i <= 0) i = 4;
20769 			if (i >= TXTMAXQLAMBDA) i = TXTMAXQLAMBDA;
20770 			TDSETSIZE(newdescript, TXTSETQLAMBDA(i));
20771 		}
20772 		if (DiaGetControl(dia, DMTX_TEXTITALIC) != 0)
20773 			TDSETITALIC(newdescript, VTITALIC); else
20774 				TDSETITALIC(newdescript, 0);
20775 		if (DiaGetControl(dia, DMTX_TEXTBOLD) != 0)
20776 			TDSETBOLD(newdescript, VTBOLD); else
20777 				TDSETBOLD(newdescript, 0);
20778 		if (DiaGetControl(dia, DMTX_TEXTUNDERLINE) != 0)
20779 			TDSETUNDERLINE(newdescript, VTUNDERLINE); else
20780 				TDSETUNDERLINE(newdescript, 0);
20781 		if (graphicshas(CANCHOOSEFACES))
20782 		{
20783 			i = us_getpopupface(DMTX_TEXTFACE, dia);
20784 			TDSETFACE(newdescript, i);
20785 		}
20786 
20787 		/* make the change */
20788 		for(win = el_topwindowpart; win != NOWINDOWPART; win = win->nextwindowpart)
20789 			(void)startobjectchange((INTBIG)win, VWINDOWPART);
20790 
20791 		if (DiaGetControl(dia, DMTX_SELECTED) != 0)
20792 		{
20793 			/* change highlighted */
20794 			len = getlength(var);
20795 			if (len > 0)
20796 			{
20797 				for(i=0; i<len; i++)
20798 				{
20799 					(void)us_makehighlight(((CHAR **)var->addr)[i], &high);
20800 					us_settextsize(&high, newdescript, changenode, changearc,
20801 						changeexport, changenonlayout, changeinstance, changecell);
20802 				}
20803 			}
20804 		} else if (DiaGetControl(dia, DMTX_ALLINCELL) != 0)
20805 		{
20806 			high.status = HIGHFROM;
20807 			high.cell = cell;
20808 			high.fromport = NOPORTPROTO;
20809 			high.fromvar = NOVARIABLE;
20810 			high.fromvarnoeval = NOVARIABLE;
20811 			for(ni = cell->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20812 			{
20813 				high.fromgeom = ni->geom;
20814 				us_settextsize(&high, newdescript, changenode, changearc,
20815 					changeexport, changenonlayout, changeinstance, changecell);
20816 			}
20817 			for(ai = cell->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
20818 			{
20819 				high.fromgeom = ai->geom;
20820 				us_settextsize(&high, newdescript, changenode, changearc,
20821 					changeexport, changenonlayout, changeinstance, changecell);
20822 			}
20823 			high.status = HIGHTEXT;
20824 			high.fromgeom = NOGEOM;
20825 			for(i=0; i<cell->numvar; i++)
20826 			{
20827 				high.fromvar = &cell->firstvar[i];
20828 				us_settextsize(&high, newdescript, changenode, changearc,
20829 					changeexport, changenonlayout, changeinstance, changecell);
20830 			}
20831 		} else if (DiaGetControl(dia, DMTX_ALLWITHVIEW) != 0)
20832 		{
20833 			/* change all with a particular view */
20834 			i = DiaGetPopupEntry(dia, DMTX_WHICHVIEW);
20835 			if (i < 0) v = NOVIEW; else
20836 				v = getview(viewlist[i]);
20837 			for(np = el_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
20838 			{
20839 				if (np->cellview != v) continue;
20840 				high.status = HIGHFROM;
20841 				high.cell = np;
20842 				high.fromport = NOPORTPROTO;
20843 				high.fromvar = NOVARIABLE;
20844 				high.fromvarnoeval = NOVARIABLE;
20845 				for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20846 				{
20847 					high.fromgeom = ni->geom;
20848 					us_settextsize(&high, newdescript, changenode, changearc,
20849 						changeexport, changenonlayout, changeinstance, changecell);
20850 				}
20851 				for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
20852 				{
20853 					high.fromgeom = ai->geom;
20854 					us_settextsize(&high, newdescript, changenode, changearc,
20855 						changeexport, changenonlayout, changeinstance, changecell);
20856 				}
20857 				high.status = HIGHTEXT;
20858 				high.fromgeom = NOGEOM;
20859 				for(i=0; i<np->numvar; i++)
20860 				{
20861 					high.fromvar = &np->firstvar[i];
20862 					us_settextsize(&high, newdescript, changenode, changearc,
20863 						changeexport, changenonlayout, changeinstance, changecell);
20864 				}
20865 			}
20866 		} else
20867 		{
20868 			/* change all in library */
20869 			for(np = el_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
20870 			{
20871 				high.status = HIGHFROM;
20872 				high.cell = np;
20873 				high.fromport = NOPORTPROTO;
20874 				high.fromvar = NOVARIABLE;
20875 				high.fromvarnoeval = NOVARIABLE;
20876 				for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20877 				{
20878 					high.fromgeom = ni->geom;
20879 					us_settextsize(&high, newdescript, changenode, changearc,
20880 						changeexport, changenonlayout, changeinstance, changecell);
20881 				}
20882 				for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
20883 				{
20884 					high.fromgeom = ai->geom;
20885 					us_settextsize(&high, newdescript, changenode, changearc,
20886 						changeexport, changenonlayout, changeinstance, changecell);
20887 				}
20888 				high.status = HIGHTEXT;
20889 				high.fromgeom = NOGEOM;
20890 				for(i=0; i<np->numvar; i++)
20891 				{
20892 					high.fromvar = &np->firstvar[i];
20893 					us_settextsize(&high, newdescript, changenode, changearc,
20894 						changeexport, changenonlayout, changeinstance, changecell);
20895 				}
20896 			}
20897 		}
20898 
20899 		/* force redisplay */
20900 		us_state |= HIGHLIGHTSET;
20901 		for(win = el_topwindowpart; win != NOWINDOWPART; win = win->nextwindowpart)
20902 			(void)endobjectchange((INTBIG)win, VWINDOWPART);
20903 	}
20904 	DiaDoneDialog(dia);
20905 	efree((CHAR *)viewlist);
20906 	return(0);
20907 }
20908 
20909 /*
20910  * Routine to determine the current range of text sizes for the dialog.
20911  */
us_setcurtextsizes(void * dia,INTBIG changenode,INTBIG changearc,INTBIG changeexport,INTBIG changenonlayout,INTBIG changeinstance,INTBIG changecell,INTBIG * lowabs,INTBIG * highabs,INTBIG * lowrel,INTBIG * highrel,CHAR ** viewlist)20912 void us_setcurtextsizes(void *dia, INTBIG changenode, INTBIG changearc, INTBIG changeexport,
20913 	INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell, INTBIG *lowabs,
20914 	INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel, CHAR **viewlist)
20915 {
20916 	REGISTER INTBIG i, len;
20917 	REGISTER VARIABLE *var;
20918 	REGISTER NODEINST *ni;
20919 	REGISTER ARCINST *ai;
20920 	REGISTER NODEPROTO *np, *cell;
20921 	REGISTER VIEW *v;
20922 	HIGHLIGHT high;
20923 
20924 	*lowabs = 0;   *highabs = -1;
20925 	*lowrel = 0;   *highrel = -1;
20926 
20927 	if (DiaGetControl(dia, DMTX_SELECTED) != 0)
20928 	{
20929 		/* examine highlighted */
20930 		var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
20931 		len = getlength(var);
20932 		if (len > 0)
20933 		{
20934 			for(i=0; i<len; i++)
20935 			{
20936 				(void)us_makehighlight(((CHAR **)var->addr)[i], &high);
20937 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20938 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20939 			}
20940 		}
20941 	} else if (DiaGetControl(dia, DMTX_ALLINCELL) != 0)
20942 	{
20943 		cell = getcurcell();
20944 		high.status = HIGHFROM;
20945 		high.cell = cell;
20946 		high.fromport = NOPORTPROTO;
20947 		high.fromvar = NOVARIABLE;
20948 		high.fromvarnoeval = NOVARIABLE;
20949 		for(ni = cell->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20950 		{
20951 			high.fromgeom = ni->geom;
20952 			us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20953 				changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20954 		}
20955 		for(ai = cell->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
20956 		{
20957 			high.fromgeom = ai->geom;
20958 			us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20959 				changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20960 		}
20961 		high.status = HIGHTEXT;
20962 		high.fromgeom = NOGEOM;
20963 		for(i=0; i<cell->numvar; i++)
20964 		{
20965 			high.fromvar = &cell->firstvar[i];
20966 			us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20967 				changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20968 		}
20969 	} else if (DiaGetControl(dia, DMTX_ALLWITHVIEW) != 0)
20970 	{
20971 		/* change all with a particular view */
20972 		i = DiaGetPopupEntry(dia, DMTX_WHICHVIEW);
20973 		if (i < 0) v = NOVIEW; else
20974 			v = getview(viewlist[i]);
20975 		for(np = el_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
20976 		{
20977 			if (np->cellview != v) continue;
20978 			high.status = HIGHFROM;
20979 			high.cell = np;
20980 			high.fromport = NOPORTPROTO;
20981 			high.fromvar = NOVARIABLE;
20982 			high.fromvarnoeval = NOVARIABLE;
20983 			for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
20984 			{
20985 				high.fromgeom = ni->geom;
20986 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20987 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20988 			}
20989 			for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
20990 			{
20991 				high.fromgeom = ai->geom;
20992 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
20993 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
20994 			}
20995 			high.status = HIGHTEXT;
20996 			high.fromgeom = NOGEOM;
20997 			for(i=0; i<np->numvar; i++)
20998 			{
20999 				high.fromvar = &np->firstvar[i];
21000 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
21001 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
21002 			}
21003 		}
21004 	} else
21005 	{
21006 		/* change all in library */
21007 		for(np = el_curlib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
21008 		{
21009 			high.status = HIGHFROM;
21010 			high.cell = np;
21011 			high.fromport = NOPORTPROTO;
21012 			high.fromvar = NOVARIABLE;
21013 			high.fromvarnoeval = NOVARIABLE;
21014 			for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
21015 			{
21016 				high.fromgeom = ni->geom;
21017 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
21018 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
21019 			}
21020 			for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
21021 			{
21022 				high.fromgeom = ai->geom;
21023 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
21024 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
21025 			}
21026 			high.status = HIGHTEXT;
21027 			high.fromgeom = NOGEOM;
21028 			for(i=0; i<np->numvar; i++)
21029 			{
21030 				high.fromvar = &np->firstvar[i];
21031 				us_gathertextsize(&high, changenode, changearc, changeexport, changenonlayout,
21032 					changeinstance, changecell, lowabs, highabs, lowrel, highrel);
21033 			}
21034 		}
21035 	}
21036 }
21037 
us_gathertextsize(HIGHLIGHT * high,INTBIG changenode,INTBIG changearc,INTBIG changeexport,INTBIG changenonlayout,INTBIG changeinstance,INTBIG changecell,INTBIG * lowabs,INTBIG * highabs,INTBIG * lowrel,INTBIG * highrel)21038 void us_gathertextsize(HIGHLIGHT *high, INTBIG changenode, INTBIG changearc, INTBIG changeexport,
21039 	INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell,
21040 	INTBIG *lowabs, INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel)
21041 {
21042 	REGISTER NODEINST *ni;
21043 	REGISTER ARCINST *ai;
21044 	REGISTER PORTEXPINST *pe;
21045 	REGISTER PORTPROTO *pp;
21046 	REGISTER INTBIG i;
21047 	REGISTER VARIABLE *var;
21048 
21049 	if ((high->status&HIGHTYPE) == HIGHFROM)
21050 	{
21051 		if (high->fromgeom->entryisnode)
21052 		{
21053 			ni = high->fromgeom->entryaddr.ni;
21054 			if (ni->proto == gen_invispinprim)
21055 			{
21056 				if (changenonlayout != 0)
21057 				{
21058 					for(i=0; i<ni->numvar; i++)
21059 					{
21060 						var = &ni->firstvar[i];
21061 						us_includetextsize(TDGETSIZE(var->textdescript), lowabs, highabs, lowrel, highrel);
21062 					}
21063 				}
21064 			} else
21065 			{
21066 				if (ni->proto->primindex == 0 && changeinstance != 0)
21067 				{
21068 					us_includetextsize(TDGETSIZE(ni->textdescript), lowabs, highabs, lowrel, highrel);
21069 				}
21070 				if (changenode != 0)
21071 				{
21072 					for(i=0; i<ni->numvar; i++)
21073 					{
21074 						var = &ni->firstvar[i];
21075 						us_includetextsize(TDGETSIZE(var->textdescript), lowabs, highabs, lowrel, highrel);
21076 					}
21077 				}
21078 			}
21079 			if (changeexport != 0)
21080 			{
21081 				for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
21082 				{
21083 					pp = pe->exportproto;
21084 					us_includetextsize(TDGETSIZE(pp->textdescript), lowabs, highabs, lowrel, highrel);
21085 				}
21086 			}
21087 		} else
21088 		{
21089 			ai = high->fromgeom->entryaddr.ai;
21090 			if (changearc != 0)
21091 			{
21092 				for(i=0; i<ai->numvar; i++)
21093 				{
21094 					var = &ai->firstvar[i];
21095 					us_includetextsize(TDGETSIZE(var->textdescript), lowabs, highabs, lowrel, highrel);
21096 				}
21097 			}
21098 		}
21099 	} else if ((high->status&HIGHTYPE) == HIGHTEXT)
21100 	{
21101 		if (high->fromvar != NOVARIABLE)
21102 		{
21103 			if (high->fromgeom == NOGEOM)
21104 			{
21105 				if (changecell != 0)
21106 					us_includetextsize(TDGETSIZE(high->fromvar->textdescript), lowabs, highabs, lowrel, highrel);
21107 			} else if (high->fromgeom->entryisnode)
21108 			{
21109 				if (high->fromport != NOPORTPROTO)
21110 				{
21111 					if (changeexport != 0)
21112 						us_includetextsize(TDGETSIZE(high->fromvar->textdescript), lowabs, highabs, lowrel, highrel);
21113 				} else
21114 				{
21115 					ni = high->fromgeom->entryaddr.ni;
21116 					if (ni->proto == gen_invispinprim)
21117 					{
21118 						if (changenonlayout != 0)
21119 							us_includetextsize(TDGETSIZE(high->fromvar->textdescript), lowabs, highabs, lowrel, highrel);
21120 					} else if (changenode != 0)
21121 						us_includetextsize(TDGETSIZE(high->fromvar->textdescript), lowabs, highabs, lowrel, highrel);
21122 				}
21123 			} else
21124 			{
21125 				if (changearc != 0)
21126 					us_includetextsize(TDGETSIZE(high->fromvar->textdescript), lowabs, highabs, lowrel, highrel);
21127 			}
21128 		} else if (high->fromport != NOPORTPROTO)
21129 		{
21130 			if (changeexport != 0)
21131 				us_includetextsize(TDGETSIZE(high->fromport->textdescript), lowabs, highabs, lowrel, highrel);
21132 		}
21133 	}
21134 }
21135 
21136 /*
21137  * Routine to add size "size" to the list of relative sizes in "lowrel" to "highrel" or absolute
21138  * sizes in "lowabs" to "highabs".
21139  */
us_includetextsize(INTBIG size,INTBIG * lowabs,INTBIG * highabs,INTBIG * lowrel,INTBIG * highrel)21140 void us_includetextsize(INTBIG size, INTBIG *lowabs, INTBIG *highabs, INTBIG *lowrel, INTBIG *highrel)
21141 {
21142 	REGISTER INTBIG thesize;
21143 
21144 	thesize = TXTGETQLAMBDA(size);
21145 	if (thesize == 0)
21146 	{
21147 		/* absolute size */
21148 		thesize = TXTGETPOINTS(size);
21149 		if (*highabs < *lowabs)
21150 		{
21151 			*highabs = *lowabs = thesize;
21152 		} else
21153 		{
21154 			if (thesize < *lowabs) *lowabs = thesize;
21155 			if (thesize > *highabs) *highabs = thesize;
21156 		}
21157 	} else
21158 	{
21159 		if (*highrel < *lowrel)
21160 		{
21161 			*highrel = *lowrel = thesize;
21162 		} else
21163 		{
21164 			if (thesize < *lowrel) *lowrel = thesize;
21165 			if (thesize > *highrel) *highrel = thesize;
21166 		}
21167 	}
21168 }
21169 
us_settextsize(HIGHLIGHT * high,UINTBIG * descript,INTBIG changenode,INTBIG changearc,INTBIG changeexport,INTBIG changenonlayout,INTBIG changeinstance,INTBIG changecell)21170 void us_settextsize(HIGHLIGHT *high, UINTBIG *descript, INTBIG changenode, INTBIG changearc,
21171 	INTBIG changeexport, INTBIG changenonlayout, INTBIG changeinstance, INTBIG changecell)
21172 {
21173 	REGISTER NODEINST *ni;
21174 	REGISTER ARCINST *ai;
21175 	REGISTER PORTEXPINST *pe;
21176 	REGISTER PORTPROTO *pp;
21177 	REGISTER INTBIG i;
21178 	UINTBIG newdescript[TEXTDESCRIPTSIZE];
21179 	REGISTER VARIABLE *var, *fromvar;
21180 
21181 	/* make sure the right variable is being altered */
21182 	fromvar = high->fromvar;
21183 	if (high->fromvarnoeval != NOVARIABLE) fromvar = high->fromvarnoeval;
21184 
21185 	if ((high->status&HIGHTYPE) == HIGHFROM)
21186 	{
21187 		if (high->fromgeom->entryisnode)
21188 		{
21189 			ni = high->fromgeom->entryaddr.ni;
21190 			if (ni->proto == gen_invispinprim)
21191 			{
21192 				if (changenonlayout != 0)
21193 				{
21194 					for(i=0; i<ni->numvar; i++)
21195 					{
21196 						var = &ni->firstvar[i];
21197 						TDCOPY(newdescript, var->textdescript);
21198 						TDSETSIZE(newdescript, TDGETSIZE(descript));
21199 						TDSETFACE(newdescript, TDGETFACE(descript));
21200 						TDSETITALIC(newdescript, TDGETITALIC(descript));
21201 						TDSETBOLD(newdescript, TDGETBOLD(descript));
21202 						TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21203 						modifydescript((INTBIG)ni, VNODEINST, var, newdescript);
21204 					}
21205 				}
21206 			} else
21207 			{
21208 				if (ni->proto->primindex == 0 && changeinstance != 0)
21209 				{
21210 					TDCOPY(newdescript, ni->textdescript);
21211 					TDSETSIZE(newdescript, TDGETSIZE(descript));
21212 					TDSETFACE(newdescript, TDGETFACE(descript));
21213 					TDSETITALIC(newdescript, TDGETITALIC(descript));
21214 					TDSETBOLD(newdescript, TDGETBOLD(descript));
21215 					TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21216 					(void)setind((INTBIG)ni, VNODEINST, x_("textdescript"), 0, newdescript[0]);
21217 					(void)setind((INTBIG)ni, VNODEINST, x_("textdescript"), 1, newdescript[1]);
21218 				}
21219 				if (changenode != 0)
21220 				{
21221 					for(i=0; i<ni->numvar; i++)
21222 					{
21223 						var = &ni->firstvar[i];
21224 						TDCOPY(newdescript, var->textdescript);
21225 						TDSETSIZE(newdescript, TDGETSIZE(descript));
21226 						TDSETFACE(newdescript, TDGETFACE(descript));
21227 						TDSETITALIC(newdescript, TDGETITALIC(descript));
21228 						TDSETBOLD(newdescript, TDGETBOLD(descript));
21229 						TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21230 						modifydescript((INTBIG)ni, VNODEINST, var, newdescript);
21231 					}
21232 				}
21233 			}
21234 			if (changeexport != 0)
21235 			{
21236 				for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
21237 				{
21238 					pp = pe->exportproto;
21239 					TDCOPY(newdescript, pp->textdescript);
21240 					TDSETSIZE(newdescript, TDGETSIZE(descript));
21241 					TDSETFACE(newdescript, TDGETFACE(descript));
21242 					TDSETITALIC(newdescript, TDGETITALIC(descript));
21243 					TDSETBOLD(newdescript, TDGETBOLD(descript));
21244 					TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21245 					(void)setind((INTBIG)pp, VPORTPROTO, x_("textdescript"), 0, newdescript[0]);
21246 					(void)setind((INTBIG)pp, VPORTPROTO, x_("textdescript"), 1, newdescript[1]);
21247 				}
21248 			}
21249 		} else
21250 		{
21251 			ai = high->fromgeom->entryaddr.ai;
21252 			if (changearc != 0)
21253 			{
21254 				for(i=0; i<ai->numvar; i++)
21255 				{
21256 					var = &ai->firstvar[i];
21257 					TDCOPY(newdescript, var->textdescript);
21258 					TDSETSIZE(newdescript, TDGETSIZE(descript));
21259 					TDSETFACE(newdescript, TDGETFACE(descript));
21260 					TDSETITALIC(newdescript, TDGETITALIC(descript));
21261 					TDSETBOLD(newdescript, TDGETBOLD(descript));
21262 					TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21263 					modifydescript((INTBIG)ai, VARCINST, var, newdescript);
21264 				}
21265 			}
21266 		}
21267 	} else if ((high->status&HIGHTYPE) == HIGHTEXT)
21268 	{
21269 		if (fromvar != NOVARIABLE)
21270 		{
21271 			TDCOPY(newdescript, fromvar->textdescript);
21272 			TDSETSIZE(newdescript, TDGETSIZE(descript));
21273 			TDSETFACE(newdescript, TDGETFACE(descript));
21274 			TDSETITALIC(newdescript, TDGETITALIC(descript));
21275 			TDSETBOLD(newdescript, TDGETBOLD(descript));
21276 			TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21277 			if (high->fromgeom == NOGEOM)
21278 			{
21279 				if (changecell != 0)
21280 				{
21281 					/* changing variable on cell */
21282 					modifydescript((INTBIG)high->cell, VNODEPROTO, fromvar, newdescript);
21283 				}
21284 			} else if (high->fromgeom->entryisnode)
21285 			{
21286 				if (high->fromport != NOPORTPROTO)
21287 				{
21288 					if (changeexport != 0)
21289 					{
21290 						/* changing export variable */
21291 						pp = high->fromport;
21292 						modifydescript((INTBIG)pp, VPORTPROTO, fromvar, newdescript);
21293 					}
21294 				} else
21295 				{
21296 					ni = high->fromgeom->entryaddr.ni;
21297 					if (ni->proto == gen_invispinprim)
21298 					{
21299 						if (changenonlayout != 0)
21300 						{
21301 							/* changing nonlayout text variable */
21302 							modifydescript((INTBIG)ni, VNODEINST, fromvar, newdescript);
21303 						}
21304 					} else if (changenode != 0)
21305 					{
21306 						/* changing node variable */
21307 						modifydescript((INTBIG)ni, VNODEINST, fromvar, newdescript);
21308 					}
21309 				}
21310 			} else
21311 			{
21312 				if (changearc != 0)
21313 				{
21314 					/* changing arc variable */
21315 					ai = high->fromgeom->entryaddr.ai;
21316 					modifydescript((INTBIG)ai, VARCINST, fromvar, newdescript);
21317 				}
21318 			}
21319 		} else if (high->fromport != NOPORTPROTO)
21320 		{
21321 			if (changeexport != 0)
21322 			{
21323 				pp = high->fromport;
21324 				ni = pp->subnodeinst;
21325 				TDCOPY(newdescript, pp->textdescript);
21326 				TDSETSIZE(newdescript, TDGETSIZE(descript));
21327 				TDSETFACE(newdescript, TDGETFACE(descript));
21328 				TDSETITALIC(newdescript, TDGETITALIC(descript));
21329 				TDSETBOLD(newdescript, TDGETBOLD(descript));
21330 				TDSETUNDERLINE(newdescript, TDGETUNDERLINE(descript));
21331 				(void)setind((INTBIG)pp, VPORTPROTO, x_("textdescript"), 0, newdescript[0]);
21332 				(void)setind((INTBIG)pp, VPORTPROTO, x_("textdescript"), 1, newdescript[1]);
21333 			}
21334 		}
21335 	}
21336 }
21337 
21338 /****************************** TEXT OPTIONS DIALOG ******************************/
21339 
21340 /* Text options */
21341 static DIALOGITEM us_deftextdialogitems[] =
21342 {
21343  /*  1 */ {0, {368,328,392,400}, BUTTON, N_("OK")},
21344  /*  2 */ {0, {368,212,392,284}, BUTTON, N_("Cancel")},
21345  /*  3 */ {0, {296,32,312,88}, RADIO, N_("Left")},
21346  /*  4 */ {0, {28,196,44,244}, EDITTEXT, x_("")},
21347  /*  5 */ {0, {232,32,248,104}, RADIO, N_("Center")},
21348  /*  6 */ {0, {248,32,264,104}, RADIO, N_("Bottom")},
21349  /*  7 */ {0, {264,32,280,88}, RADIO, N_("Top")},
21350  /*  8 */ {0, {280,32,296,96}, RADIO, N_("Right")},
21351  /*  9 */ {0, {312,32,328,128}, RADIO, N_("Lower right")},
21352  /* 10 */ {0, {328,32,344,128}, RADIO, N_("Lower left")},
21353  /* 11 */ {0, {344,32,360,128}, RADIO, N_("Upper right")},
21354  /* 12 */ {0, {360,32,376,120}, RADIO, N_("Upper left")},
21355  /* 13 */ {0, {376,32,392,104}, RADIO, N_("Boxed")},
21356  /* 14 */ {0, {68,8,84,135}, RADIO, N_("Exports & Ports")},
21357  /* 15 */ {0, {216,8,232,103}, MESSAGE, N_("Text corner:")},
21358  /* 16 */ {0, {232,136,264,168}, ICON, (CHAR *)us_icon200},
21359  /* 17 */ {0, {264,136,296,168}, ICON, (CHAR *)us_icon201},
21360  /* 18 */ {0, {296,136,328,168}, ICON, (CHAR *)us_icon202},
21361  /* 19 */ {0, {328,136,360,168}, ICON, (CHAR *)us_icon203},
21362  /* 20 */ {0, {360,136,392,168}, ICON, (CHAR *)us_icon204},
21363  /* 21 */ {0, {336,308,352,380}, RADIO, N_("Outside")},
21364  /* 22 */ {0, {248,224,264,296}, RADIO, N_("Off")},
21365  /* 23 */ {0, {216,204,232,400}, MESSAGE, N_("Smart Vertical Placement:")},
21366  /* 24 */ {0, {236,308,252,380}, RADIO, N_("Inside")},
21367  /* 25 */ {0, {260,308,276,380}, RADIO, N_("Outside")},
21368  /* 26 */ {0, {324,224,340,296}, RADIO, N_("Off")},
21369  /* 27 */ {0, {292,204,308,400}, MESSAGE, N_("Smart Horizontal Placement:")},
21370  /* 28 */ {0, {312,308,328,380}, RADIO, N_("Inside")},
21371  /* 29 */ {0, {184,8,200,280}, CHECK, N_("New text visible only inside cell")},
21372  /* 30 */ {0, {160,100,176,224}, POPUP, x_("")},
21373  /* 31 */ {0, {160,8,176,99}, MESSAGE, N_("Text editor:")},
21374  /* 32 */ {0, {4,12,20,411}, MESSAGE, N_("Default text information for different types of text:")},
21375  /* 33 */ {0, {52,196,68,244}, EDITTEXT, x_("")},
21376  /* 34 */ {0, {28,8,44,135}, RADIO, N_("Nodes")},
21377  /* 35 */ {0, {80,140,96,228}, MESSAGE, N_("Type face:")},
21378  /* 36 */ {0, {48,8,64,135}, RADIO, N_("Arcs")},
21379  /* 37 */ {0, {28,252,44,412}, RADIO, N_("Points (max 63)")},
21380  /* 38 */ {0, {108,8,124,135}, RADIO, N_("Instance names")},
21381  /* 39 */ {0, {52,252,68,412}, RADIO, N_("Lambda (max 127.75)")},
21382  /* 40 */ {0, {88,8,104,135}, RADIO, N_("Nonlayout text")},
21383  /* 41 */ {0, {208,8,209,412}, DIVIDELINE, x_("")},
21384  /* 42 */ {0, {152,8,153,412}, DIVIDELINE, x_("")},
21385  /* 43 */ {0, {209,188,392,189}, DIVIDELINE, x_("")},
21386  /* 44 */ {0, {100,140,116,376}, POPUP, x_("")},
21387  /* 45 */ {0, {128,140,144,212}, CHECK, N_("Italic")},
21388  /* 46 */ {0, {128,236,144,296}, CHECK, N_("Bold")},
21389  /* 47 */ {0, {128,324,144,412}, CHECK, N_("Underline")},
21390  /* 48 */ {0, {40,140,56,188}, MESSAGE, N_("Size")},
21391  /* 49 */ {0, {128,8,144,135}, RADIO, N_("Cell text")}
21392 };
21393 static DIALOG us_deftextdialog = {{50,75,451,497}, N_("Text Options"), 0, 49, us_deftextdialogitems, 0, 0};
21394 
21395 /* special items for "text options" dialog: */
21396 #define DTXO_GRABLEFT        3		/* left (radio) */
21397 #define DTXO_ABSTEXTSIZE     4		/* absolute text size (edit text) */
21398 #define DTXO_GRABCENTER      5		/* center (radio) */
21399 #define DTXO_GRABBOT         6		/* bottom (radio) */
21400 #define DTXO_GRABTOP         7		/* top (radio) */
21401 #define DTXO_GRABRIGHT       8		/* right (radio) */
21402 #define DTXO_GRABLOWRIGHT    9		/* lower right (radio) */
21403 #define DTXO_GRABLOWLEFT    10		/* lower left (radio) */
21404 #define DTXO_GRABUPRIGHT    11		/* upper right (radio) */
21405 #define DTXO_GRABUPLEFT     12		/* upper left (radio) */
21406 #define DTXO_GRABBOXED      13		/* boxed (radio) */
21407 #define DTXO_EXPORTSIZE     14		/* set default export text size (radio) */
21408 #define DTXO_LOWICON        16		/* low icon (icon) */
21409 #define DTXO_HIGHICON       20		/* high icon (icon) */
21410 #define DTXO_SMARTHOROUT    21		/* smart horizontal outside (radio) */
21411 #define DTXO_SMARTVERTOFF   22		/* smart vertical off (radio) */
21412 #define DTXO_SMARTVERTIN    24		/* smart vertical inside (radio) */
21413 #define DTXO_SMARTVERTOUT   25		/* smart vertical outside (radio) */
21414 #define DTXO_SMARTHOROFF    26		/* smart horizontal off (radio) */
21415 #define DTXO_SMARTHORIN     28		/* smart horizontal inside (radio) */
21416 #define DTXO_ONLYINSIDE     29		/* only inside cell (check) */
21417 #define DTXO_TEXTEDITOR     30		/* text editor (popup) */
21418 #define DTXO_RELTEXTSIZE    33		/* relative text size (edit text) */
21419 #define DTXO_NODESIZE       34		/* set default node text size (radio) */
21420 #define DTXO_TEXTFACE_L     35		/* text face label (stat text) */
21421 #define DTXO_ARCSIZE        36		/* set default arc text size (radio) */
21422 #define DTXO_ABSTEXTSIZE_L  37		/* absolute text size label (radio) */
21423 #define DTXO_INSTSIZE       38		/* set default cell instance text size (radio) */
21424 #define DTXO_RELTEXTSIZE_L  39		/* relative text size label (radio) */
21425 #define DTXO_NONLAYOUTSIZE  40		/* set default invis-pin text size (radio) */
21426 #define DTXO_TEXTFACE       44		/* text face (popup) */
21427 #define DTXO_TEXTITALIC     45		/* text italic (check) */
21428 #define DTXO_TEXTBOLD       46		/* text bold (check) */
21429 #define DTXO_TEXTUNDERLINE  47		/* text underline (check) */
21430 #define DTXO_CELLSIZE       49		/* set default cell text size (radio) */
21431 
21432 void us_setdeftextinfo(UINTBIG *descript, void *dia);
21433 
us_deftextdlog(CHAR * prompt)21434 INTBIG us_deftextdlog(CHAR *prompt)
21435 {
21436 	Q_UNUSED( prompt );
21437 	INTBIG itemHit, i, j, ecount, cureditor;
21438 	INTBIG x, y;
21439 	CHAR *newlang[16];
21440 	REGISTER VARIABLE *var;
21441 	REGISTER WINDOWPART *w;
21442 	REGISTER INTBIG grabpoint, textstyle, smarthstyle, smartvstyle;
21443 	REGISTER void *dia;
21444 	UINTBIG fontnode[TEXTDESCRIPTSIZE], fontarc[TEXTDESCRIPTSIZE],
21445 		fontexport[TEXTDESCRIPTSIZE], fontnonlayout[TEXTDESCRIPTSIZE],
21446 		fontinst[TEXTDESCRIPTSIZE], fontcell[TEXTDESCRIPTSIZE],
21447 		ofontnode[TEXTDESCRIPTSIZE], ofontarc[TEXTDESCRIPTSIZE],
21448 		ofontexport[TEXTDESCRIPTSIZE], ofontnonlayout[TEXTDESCRIPTSIZE],
21449 		ofontinst[TEXTDESCRIPTSIZE], ofontcell[TEXTDESCRIPTSIZE], *curdescript;
21450 	RECTAREA itemRect;
21451 	static struct butlist poslist[10] =
21452 	{
21453 		{VTPOSCENT,      DTXO_GRABCENTER},
21454 		{VTPOSUP,        DTXO_GRABBOT},
21455 		{VTPOSDOWN,      DTXO_GRABTOP},
21456 		{VTPOSLEFT,      DTXO_GRABRIGHT},
21457 		{VTPOSRIGHT,     DTXO_GRABLEFT},
21458 		{VTPOSUPLEFT,    DTXO_GRABLOWRIGHT},
21459 		{VTPOSUPRIGHT,   DTXO_GRABLOWLEFT},
21460 		{VTPOSDOWNLEFT,  DTXO_GRABUPRIGHT},
21461 		{VTPOSDOWNRIGHT, DTXO_GRABUPLEFT},
21462 		{VTPOSBOXED,     DTXO_GRABBOXED}
21463 	};
21464 
21465 	/* display the default text dialog box */
21466 	dia = DiaInitDialog(&us_deftextdialog);
21467 	if (dia == 0) return(0);
21468 
21469 	/* load the editor choice popup */
21470 	for(ecount=0; us_editortable[ecount].editorname != 0; ecount++)
21471 		newlang[ecount] = us_editortable[ecount].editorname;
21472 	DiaSetPopup(dia, DTXO_TEXTEDITOR, ecount, newlang);
21473 	cureditor = 0;
21474 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING, us_text_editorkey);
21475 	if (var != NOVARIABLE)
21476 	{
21477 		for(i=0; i<ecount; i++)
21478 			if (namesame(newlang[i], (CHAR *)var->addr) == 0) break;
21479 		if (i < ecount) cureditor = i;
21480 	}
21481 	DiaSetPopupEntry(dia, DTXO_TEXTEDITOR, cureditor);
21482 
21483 	/* make sure there are no text editors running */
21484 	DiaUnDimItem(dia, DTXO_TEXTEDITOR);
21485 	for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
21486 		if ((w->state&WINDOWTYPE) == TEXTWINDOW || (w->state&WINDOWTYPE) == POPTEXTWINDOW)
21487 	{
21488 		DiaDimItem(dia, DTXO_TEXTEDITOR);
21489 		break;
21490 	}
21491 
21492 	/* set current defaults */
21493 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_style"));
21494 	if (var == NOVARIABLE) textstyle = VTPOSCENT; else textstyle = var->addr;
21495 	grabpoint = textstyle & VTPOSITION;
21496 	for(i=0; i<10; i++) if (grabpoint == (INTBIG)poslist[i].value)
21497 	{
21498 		DiaSetControl(dia, poslist[i].button, 1);
21499 		break;
21500 	}
21501 	if ((textstyle&VTINTERIOR) != 0) DiaSetControl(dia, DTXO_ONLYINSIDE, 1);
21502 
21503 	var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_default_text_smart_style"));
21504 	if (var == NOVARIABLE)
21505 	{
21506 		smarthstyle = smartvstyle = 0;
21507 	} else
21508 	{
21509 		smarthstyle = var->addr & 03;
21510 		smartvstyle = (var->addr >> 2) & 03;
21511 	}
21512 	switch (smarthstyle)
21513 	{
21514 		case 1:  DiaSetControl(dia, DTXO_SMARTHORIN, 1);  break;
21515 		case 2:  DiaSetControl(dia, DTXO_SMARTHOROUT, 1);  break;
21516 		default: DiaSetControl(dia, DTXO_SMARTHOROFF, 1);  break;
21517 	}
21518 	switch (smartvstyle)
21519 	{
21520 		case 1:  DiaSetControl(dia, DTXO_SMARTVERTIN, 1);  break;
21521 		case 2:  DiaSetControl(dia, DTXO_SMARTVERTOUT, 1);  break;
21522 		default: DiaSetControl(dia, DTXO_SMARTVERTOFF, 1);  break;
21523 	}
21524 
21525 	/* get default text information */
21526 	if (graphicshas(CANCHOOSEFACES))
21527 	{
21528 		DiaUnDimItem(dia, DTXO_TEXTFACE_L);
21529 		us_setpopupface(DTXO_TEXTFACE, 0, TRUE, dia);
21530 	} else
21531 	{
21532 		DiaDimItem(dia, DTXO_TEXTFACE_L);
21533 	}
21534 	if (graphicshas(CANMODIFYFONTS))
21535 	{
21536 		DiaUnDimItem(dia, DTXO_TEXTITALIC);
21537 		DiaUnDimItem(dia, DTXO_TEXTBOLD);
21538 		DiaUnDimItem(dia, DTXO_TEXTUNDERLINE);
21539 	} else
21540 	{
21541 		DiaDimItem(dia, DTXO_TEXTITALIC);
21542 		DiaDimItem(dia, DTXO_TEXTBOLD);
21543 		DiaDimItem(dia, DTXO_TEXTUNDERLINE);
21544 	}
21545 	TDCLEAR(fontnode);      defaulttextsize(3, fontnode);      TDCOPY(ofontnode, fontnode);
21546 	TDCLEAR(fontarc);       defaulttextsize(4, fontarc);       TDCOPY(ofontarc, fontarc);
21547 	TDCLEAR(fontexport);    defaulttextsize(1, fontexport);    TDCOPY(ofontexport, fontexport);
21548 	TDCLEAR(fontnonlayout); defaulttextsize(2, fontnonlayout); TDCOPY(ofontnonlayout, fontnonlayout);
21549 	TDCLEAR(fontinst);      defaulttextsize(5, fontinst);      TDCOPY(ofontinst, fontinst);
21550 	TDCLEAR(fontcell);      defaulttextsize(6, fontcell);      TDCOPY(ofontcell, fontcell);
21551 	DiaSetControl(dia, DTXO_NODESIZE, 1);
21552 	curdescript = fontnode;
21553 	us_setdeftextinfo(curdescript, dia);
21554 
21555 	/* loop until done */
21556 	for(;;)
21557 	{
21558 		itemHit = DiaNextHit(dia);
21559 		if (itemHit == OK || itemHit == CANCEL) break;
21560 
21561 		if (itemHit >= DTXO_LOWICON && itemHit <= DTXO_HIGHICON)
21562 		{
21563 			DiaItemRect(dia, itemHit, &itemRect);
21564 			DiaGetMouse(dia, &x, &y);
21565 			itemHit = (itemHit-DTXO_LOWICON) * 2;
21566 			if (y > (itemRect.top + itemRect.bottom) / 2) itemHit++;
21567 			itemHit = poslist[itemHit].button;
21568 		}
21569 
21570 		/* hits on the orientation buttons */
21571 		for(i=0; i<10; i++) if (itemHit == poslist[i].button)
21572 		{
21573 			DiaSetControl(dia, poslist[grabpoint].button, 0);
21574 			grabpoint = i;
21575 			DiaSetControl(dia, poslist[i].button, 1);
21576 			break;
21577 		}
21578 
21579 		if (itemHit == DTXO_SMARTVERTOFF || itemHit == DTXO_SMARTVERTIN ||
21580 			itemHit == DTXO_SMARTVERTOUT)
21581 		{
21582 			DiaSetControl(dia, DTXO_SMARTVERTOFF, 0);
21583 			DiaSetControl(dia, DTXO_SMARTVERTIN, 0);
21584 			DiaSetControl(dia, DTXO_SMARTVERTOUT, 0);
21585 			DiaSetControl(dia, itemHit, 1);
21586 			continue;
21587 		}
21588 		if (itemHit == DTXO_SMARTHOROFF || itemHit == DTXO_SMARTHORIN || itemHit == DTXO_SMARTHOROUT)
21589 		{
21590 			DiaSetControl(dia, DTXO_SMARTHOROFF, 0);
21591 			DiaSetControl(dia, DTXO_SMARTHORIN, 0);
21592 			DiaSetControl(dia, DTXO_SMARTHOROUT, 0);
21593 			DiaSetControl(dia, itemHit, 1);
21594 			continue;
21595 		}
21596 		if (itemHit == DTXO_ONLYINSIDE)
21597 		{
21598 			DiaSetControl(dia, itemHit, 1 - DiaGetControl(dia, itemHit));
21599 			continue;
21600 		}
21601 		if (itemHit == DTXO_NODESIZE || itemHit == DTXO_ARCSIZE ||
21602 			itemHit == DTXO_EXPORTSIZE || itemHit == DTXO_NONLAYOUTSIZE ||
21603 			itemHit == DTXO_INSTSIZE || itemHit == DTXO_CELLSIZE)
21604 		{
21605 			DiaSetControl(dia, DTXO_NODESIZE, 0);
21606 			DiaSetControl(dia, DTXO_ARCSIZE, 0);
21607 			DiaSetControl(dia, DTXO_EXPORTSIZE, 0);
21608 			DiaSetControl(dia, DTXO_NONLAYOUTSIZE, 0);
21609 			DiaSetControl(dia, DTXO_INSTSIZE, 0);
21610 			DiaSetControl(dia, DTXO_CELLSIZE, 0);
21611 			DiaSetControl(dia, itemHit, 1);
21612 			switch (itemHit)
21613 			{
21614 				case DTXO_NODESIZE:      curdescript = fontnode;          break;
21615 				case DTXO_ARCSIZE:       curdescript = fontarc;           break;
21616 				case DTXO_EXPORTSIZE:    curdescript = fontexport;        break;
21617 				case DTXO_NONLAYOUTSIZE: curdescript = fontnonlayout;     break;
21618 				case DTXO_INSTSIZE:      curdescript = fontinst;          break;
21619 				case DTXO_CELLSIZE:      curdescript = fontcell;          break;
21620 			}
21621 			us_setdeftextinfo(curdescript, dia);
21622 			continue;
21623 		}
21624 		if (itemHit == DTXO_ABSTEXTSIZE_L || itemHit == DTXO_RELTEXTSIZE_L)
21625 		{
21626 			DiaSetControl(dia, DTXO_ABSTEXTSIZE_L, 0);
21627 			DiaSetControl(dia, DTXO_RELTEXTSIZE_L, 0);
21628 			DiaSetControl(dia, itemHit, 1);
21629 			if (itemHit == DTXO_ABSTEXTSIZE_L)
21630 			{
21631 				DiaUnDimItem(dia, DTXO_ABSTEXTSIZE);
21632 				DiaDimItem(dia, DTXO_RELTEXTSIZE);
21633 				itemHit = DTXO_ABSTEXTSIZE;
21634 			} else
21635 			{
21636 				DiaUnDimItem(dia, DTXO_RELTEXTSIZE);
21637 				DiaDimItem(dia, DTXO_ABSTEXTSIZE);
21638 				itemHit = DTXO_RELTEXTSIZE;
21639 			}
21640 		}
21641 		if (itemHit == DTXO_ABSTEXTSIZE || itemHit == DTXO_RELTEXTSIZE)
21642 		{
21643 			if (DiaGetControl(dia, DTXO_ABSTEXTSIZE_L) != 0)
21644 			{
21645 				i = eatoi(DiaGetText(dia, DTXO_ABSTEXTSIZE));
21646 				if (i <= 0) i = 4;
21647 				if (i >= TXTMAXPOINTS) i = TXTMAXPOINTS;
21648 				TDSETSIZE(curdescript, TXTSETPOINTS(i));
21649 			} else
21650 			{
21651 				i = atofr(DiaGetText(dia, DTXO_RELTEXTSIZE)) * 4 / WHOLE;
21652 				if (i <= 0) i = 4;
21653 				if (i >= TXTMAXQLAMBDA) i = TXTMAXQLAMBDA;
21654 				TDSETSIZE(curdescript, TXTSETQLAMBDA(i));
21655 			}
21656 			continue;
21657 		}
21658 		if (itemHit == DTXO_TEXTFACE)
21659 		{
21660 			TDSETFACE(curdescript, us_getpopupface(DTXO_TEXTFACE, dia));
21661 			continue;
21662 		}
21663 		if (itemHit == DTXO_TEXTITALIC)
21664 		{
21665 			i = 1 - DiaGetControl(dia, itemHit);
21666 			DiaSetControl(dia, itemHit, i);
21667 			if (i == 0) TDSETITALIC(curdescript, 0); else
21668 				TDSETITALIC(curdescript, VTITALIC);
21669 			continue;
21670 		}
21671 		if (itemHit == DTXO_TEXTBOLD)
21672 		{
21673 			i = 1 - DiaGetControl(dia, itemHit);
21674 			DiaSetControl(dia, itemHit, i);
21675 			if (i == 0) TDSETBOLD(curdescript, 0); else
21676 				TDSETBOLD(curdescript, VTBOLD);
21677 			continue;
21678 		}
21679 		if (itemHit == DTXO_TEXTUNDERLINE)
21680 		{
21681 			i = 1 - DiaGetControl(dia, itemHit);
21682 			DiaSetControl(dia, itemHit, i);
21683 			if (i == 0) TDSETUNDERLINE(curdescript, 0); else
21684 				TDSETUNDERLINE(curdescript, VTUNDERLINE);
21685 			continue;
21686 		}
21687 	}
21688 
21689 	if (itemHit == OK)
21690 	{
21691 		if (TDDIFF(ofontnode, fontnode))
21692 		{
21693 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_node_text_size"),
21694 				(INTBIG)fontnode, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21695 		}
21696 
21697 		if (TDDIFF(ofontarc, fontarc))
21698 		{
21699 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_arc_text_size"),
21700 				(INTBIG)fontarc, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21701 		}
21702 
21703 		if (TDDIFF(ofontexport, fontexport))
21704 		{
21705 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_export_text_size"),
21706 				(INTBIG)fontexport, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21707 		}
21708 
21709 		if (TDDIFF(ofontnonlayout, fontnonlayout))
21710 		{
21711 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_nonlayout_text_size"),
21712 				(INTBIG)fontnonlayout, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21713 		}
21714 
21715 		if (TDDIFF(ofontinst, fontinst))
21716 		{
21717 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_instance_text_size"),
21718 				(INTBIG)fontinst, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21719 		}
21720 
21721 		if (TDDIFF(ofontcell, fontcell))
21722 		{
21723 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_facet_text_size"),
21724 				(INTBIG)fontcell, VINTEGER|VISARRAY|(TEXTDESCRIPTSIZE<<VLENGTHSH));
21725 		}
21726 
21727 		if (DiaGetControl(dia, DTXO_ONLYINSIDE) != 0) grabpoint |= VTINTERIOR;
21728 		if (grabpoint != textstyle)
21729 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_style"), grabpoint, VINTEGER);
21730 		if (DiaGetControl(dia, DTXO_SMARTHOROFF) != 0) i = 0; else
21731 			if (DiaGetControl(dia, DTXO_SMARTHORIN) != 0) i = 1; else
21732 				if (DiaGetControl(dia, DTXO_SMARTHOROUT) != 0) i = 2;
21733 		if (DiaGetControl(dia, DTXO_SMARTVERTOFF) != 0) j = 0; else
21734 			if (DiaGetControl(dia, DTXO_SMARTVERTIN) != 0) j = 1; else
21735 				if (DiaGetControl(dia, DTXO_SMARTVERTOUT) != 0) j = 2;
21736 		if (smarthstyle != i || smartvstyle != j)
21737 			setval((INTBIG)us_tool, VTOOL, x_("USER_default_text_smart_style"),
21738 				i | (j << 2), VINTEGER);
21739 		i = DiaGetPopupEntry(dia, DTXO_TEXTEDITOR);
21740 		if (i != cureditor)
21741 		{
21742 			setvalkey((INTBIG)us_tool, VTOOL, us_text_editorkey, (INTBIG)us_editortable[i].editorname,
21743 				VSTRING);
21744 		}
21745 	}
21746 	DiaDoneDialog(dia);
21747 	return(0);
21748 }
21749 
us_setdeftextinfo(UINTBIG * descript,void * dia)21750 void us_setdeftextinfo(UINTBIG *descript, void *dia)
21751 {
21752 	INTBIG i;
21753 	CHAR buf[30];
21754 
21755 	i = TDGETSIZE(descript);
21756 	if (TXTGETPOINTS(i) != 0)
21757 	{
21758 		/* show point size */
21759 		esnprintf(buf, 30, x_("%ld"), TXTGETPOINTS(i));
21760 		DiaUnDimItem(dia, DTXO_ABSTEXTSIZE);
21761 		DiaSetText(dia, DTXO_ABSTEXTSIZE, buf);
21762 		DiaSetControl(dia, DTXO_ABSTEXTSIZE_L, 1);
21763 
21764 		/* clear lambda amount */
21765 		DiaSetText(dia, DTXO_RELTEXTSIZE, x_(""));
21766 		DiaDimItem(dia, DTXO_RELTEXTSIZE);
21767 		DiaSetControl(dia, DTXO_RELTEXTSIZE_L, 0);
21768 	} else if (TXTGETQLAMBDA(i) != 0)
21769 	{
21770 		/* show lambda amount */
21771 		DiaUnDimItem(dia, DTXO_RELTEXTSIZE);
21772 		DiaSetText(dia, DTXO_RELTEXTSIZE, frtoa(TXTGETQLAMBDA(i) * WHOLE / 4));
21773 		DiaSetControl(dia, DTXO_RELTEXTSIZE_L, 1);
21774 
21775 		/* clear point size */
21776 		DiaSetText(dia, DTXO_ABSTEXTSIZE, x_(""));
21777 		DiaDimItem(dia, DTXO_ABSTEXTSIZE);
21778 		DiaSetControl(dia, DTXO_ABSTEXTSIZE_L, 0);
21779 	}
21780 	us_setpopupface(DTXO_TEXTFACE, TDGETFACE(descript), FALSE, dia);
21781 	if (graphicshas(CANMODIFYFONTS))
21782 	{
21783 		if (TDGETITALIC(descript) != 0) DiaSetControl(dia, DTXO_TEXTITALIC, 1); else
21784 			DiaSetControl(dia, DTXO_TEXTITALIC, 0);
21785 		if (TDGETBOLD(descript) != 0) DiaSetControl(dia, DTXO_TEXTBOLD, 1); else
21786 			DiaSetControl(dia, DTXO_TEXTBOLD, 0);
21787 		if (TDGETUNDERLINE(descript) != 0) DiaSetControl(dia, DTXO_TEXTUNDERLINE, 1); else
21788 			DiaSetControl(dia, DTXO_TEXTUNDERLINE, 0);
21789 	}
21790 }
21791 
21792 /****************************** UNITS DIALOG ******************************/
21793 
21794 /* Units */
21795 static DIALOGITEM us_unitsdialogitems[] =
21796 {
21797  /*  1 */ {0, {292,509,316,581}, BUTTON, N_("OK")},
21798  /*  2 */ {0, {256,509,280,581}, BUTTON, N_("Cancel")},
21799  /*  3 */ {0, {196,512,212,588}, EDITTEXT, x_("")},
21800  /*  4 */ {0, {196,308,212,508}, MESSAGE, N_("Lambda size (internal units):")},
21801  /*  5 */ {0, {32,132,48,292}, POPUP, x_("")},
21802  /*  6 */ {0, {8,8,24,124}, MESSAGE, N_("Display Units:")},
21803  /*  7 */ {0, {238,132,254,292}, POPUP, x_("")},
21804  /*  8 */ {0, {214,8,230,126}, MESSAGE, N_("Internal Units:")},
21805  /*  9 */ {0, {52,308,188,588}, SCROLL, x_("")},
21806  /* 10 */ {0, {32,380,48,500}, MESSAGE, N_("Technologies:")},
21807  /* 11 */ {0, {8,452,24,588}, MESSAGE, x_("")},
21808  /* 12 */ {0, {8,308,24,452}, MESSAGE, N_("Current library:")},
21809  /* 13 */ {0, {308,324,324,476}, RADIO, N_("Change all libraries")},
21810  /* 14 */ {0, {284,324,300,476}, RADIO, N_("Change current library")},
21811  /* 15 */ {0, {8,300,324,301}, DIVIDELINE, x_("")},
21812  /* 16 */ {0, {220,512,236,588}, MESSAGE, x_("")},
21813  /* 17 */ {0, {260,324,276,476}, RADIO, N_("Change no libraries")},
21814  /* 18 */ {0, {236,308,252,476}, MESSAGE, N_("When changing lambda:")},
21815  /* 19 */ {0, {32,16,48,132}, MESSAGE, N_("Distance:")},
21816  /* 20 */ {0, {56,132,72,292}, POPUP, x_("")},
21817  /* 21 */ {0, {238,16,254,132}, MESSAGE, N_("Distance:")},
21818  /* 22 */ {0, {56,16,72,132}, MESSAGE, N_("Resistance:")},
21819  /* 23 */ {0, {80,132,96,292}, POPUP, x_("")},
21820  /* 24 */ {0, {152,16,168,132}, MESSAGE, N_("Voltage:")},
21821  /* 25 */ {0, {80,16,96,132}, MESSAGE, N_("Capacitance:")},
21822  /* 26 */ {0, {104,132,120,292}, POPUP, x_("")},
21823  /* 27 */ {0, {176,16,192,132}, MESSAGE, N_("Time:")},
21824  /* 28 */ {0, {104,16,120,132}, MESSAGE, N_("Inductance:")},
21825  /* 29 */ {0, {128,132,144,292}, POPUP, x_("")},
21826  /* 30 */ {0, {176,132,192,292}, POPUP, x_("")},
21827  /* 31 */ {0, {128,16,144,132}, MESSAGE, N_("Current:")},
21828  /* 32 */ {0, {152,132,168,292}, POPUP, x_("")},
21829  /* 33 */ {0, {258,16,274,294}, MESSAGE, N_("(read manual before changing this)")}
21830 };
21831 static DIALOG us_unitsdialog = {{50,75,383,672}, N_("Change Units"), 0, 33, us_unitsdialogitems, 0, 0};
21832 static BOOLEAN us_topoftechlambda(CHAR **c);
21833 static CHAR *us_nexttechlambda(void);
21834 
21835 /* special items for the "units" dialog: */
21836 #define DUNO_LAMBDA       3		/* Lambda (edit text) */
21837 #define DUNO_DISTDUNIT    5		/* Display distance units (popup) */
21838 #define DUNO_DISTIUNIT    7		/* Internal distance units (popup) */
21839 #define DUNO_TECHLIST     9		/* Technologies (scroll) */
21840 #define DUNO_CURLIB      11		/* Current lib (stat text) */
21841 #define DUNO_CHGALLLIBS  13		/* Change all libs (radio) */
21842 #define DUNO_CHGTHISLIB  14		/* Change this lib (radio) */
21843 #define DUNO_MICRONS     16		/* Micron value (stat text) */
21844 #define DUNO_CHGNOLIBS   17		/* Change no libs (radio) */
21845 #define DUNO_RESDUNIT    20		/* Display resistance units (popup) */
21846 #define DUNO_CAPDUNIT    23		/* Display capacitance units (popup) */
21847 #define DUNO_INDDUNIT    26		/* Display inductance units (popup) */
21848 #define DUNO_CURDUNIT    29		/* Display current units (popup) */
21849 #define DUNO_TIMEDUNIT   30		/* Display time units (popup) */
21850 #define DUNO_VOLTDUNIT   32		/* Display voltage units (popup) */
21851 
us_lambdadlog(void)21852 INTBIG us_lambdadlog(void)
21853 {
21854 	REGISTER INTBIG itemHit, i, count, newiunit, newdunit, oldiunit, olddunit,
21855 		which, newlam, oldlam, *newlamarray, listlen;
21856 	BOOLEAN toldposlambda, dochange;
21857 	float lambdainmicrons;
21858 	REGISTER WINDOWPART *w;
21859 	CHAR ent[30], *newlang[8], *pt, *line;
21860 	REGISTER TECHNOLOGY **techarray, *tech, *curtech;
21861 	static CHAR *dispunitnames[8] = {N_("Lambda units"), N_("Inches"), N_("Centimeters"),
21862 		N_("Millimeters"), N_("Mils"), N_("Microns"), N_("Centimicrons"), N_("Nanometers")};
21863 	static CHAR *intunitnames[2] = {N_("Half-Nanometers"), N_("Half-Decimicrons")};
21864 	REGISTER void *infstr;
21865 	REGISTER void *dia;
21866 
21867 	/* display the units dialog box */
21868 	dia = DiaInitDialog(&us_unitsdialog);
21869 	if (dia == 0) return(0);
21870 	DiaSetText(dia, DUNO_CURLIB, el_curlib->libname);
21871 	DiaSetControl(dia, DUNO_CHGALLLIBS, 1);
21872 
21873 	/* set the internal units */
21874 	for(i=0; i<2; i++) newlang[i] = TRANSLATE(intunitnames[i]);
21875 	DiaSetPopup(dia, DUNO_DISTIUNIT, 2, newlang);
21876 	oldiunit = el_units&INTERNALUNITS;
21877 	switch (oldiunit)
21878 	{
21879 		case INTUNITHNM:   DiaSetPopupEntry(dia, DUNO_DISTIUNIT, 0);   break;
21880 		case INTUNITHDMIC: DiaSetPopupEntry(dia, DUNO_DISTIUNIT, 1);   break;
21881 	}
21882 
21883 	/* load the display units */
21884 	for(i=0; i<8; i++) newlang[i] = TRANSLATE(dispunitnames[i]);
21885 	DiaSetPopup(dia, DUNO_DISTDUNIT, 8, newlang);
21886 	olddunit = el_units&DISPLAYUNITS;
21887 	switch (olddunit)
21888 	{
21889 		case DISPUNITLAMBDA: DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 0);   break;
21890 		case DISPUNITINCH:   DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 1);   break;
21891 		case DISPUNITCM:     DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 2);   break;
21892 		case DISPUNITMM:     DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 3);   break;
21893 		case DISPUNITMIL:    DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 4);   break;
21894 		case DISPUNITMIC:    DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 5);   break;
21895 		case DISPUNITCMIC:   DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 6);   break;
21896 		case DISPUNITNM:     DiaSetPopupEntry(dia, DUNO_DISTDUNIT, 7);   break;
21897 	}
21898 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_resistancenames[i]);
21899 	DiaSetPopup(dia, DUNO_RESDUNIT, 4, newlang);
21900 	DiaSetPopupEntry(dia, DUNO_RESDUNIT,
21901 		(us_electricalunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH);
21902 	for(i=0; i<6; i++) newlang[i] = TRANSLATE(us_capacitancenames[i]);
21903 	DiaSetPopup(dia, DUNO_CAPDUNIT, 6, newlang);
21904 	DiaSetPopupEntry(dia, DUNO_CAPDUNIT,
21905 		(us_electricalunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH);
21906 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_inductancenames[i]);
21907 	DiaSetPopup(dia, DUNO_INDDUNIT, 4, newlang);
21908 	DiaSetPopupEntry(dia, DUNO_INDDUNIT,
21909 		(us_electricalunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH);
21910 	for(i=0; i<3; i++) newlang[i] = TRANSLATE(us_currentnames[i]);
21911 	DiaSetPopup(dia, DUNO_CURDUNIT, 3, newlang);
21912 	DiaSetPopupEntry(dia, DUNO_CURDUNIT,
21913 		(us_electricalunits&INTERNALCURUNITS) >> INTERNALCURUNITSSH);
21914 	for(i=0; i<4; i++) newlang[i] = TRANSLATE(us_voltagenames[i]);
21915 	DiaSetPopup(dia, DUNO_VOLTDUNIT, 4, newlang);
21916 	DiaSetPopupEntry(dia, DUNO_VOLTDUNIT,
21917 		(us_electricalunits&INTERNALVOLTUNITS) >> INTERNALVOLTUNITSSH);
21918 	for(i=0; i<6; i++) newlang[i] = TRANSLATE(us_timenames[i]);
21919 	DiaSetPopup(dia, DUNO_TIMEDUNIT, 6, newlang);
21920 	DiaSetPopupEntry(dia, DUNO_TIMEDUNIT,
21921 		(us_electricalunits&INTERNALTIMEUNITS) >> INTERNALTIMEUNITSSH);
21922 
21923 	/* load the list of technologies */
21924 	curtech = el_curtech;
21925 	if (curtech == sch_tech || curtech == gen_tech || curtech == art_tech)
21926 		curtech = defschematictechnology(el_curtech);
21927 	for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
21928 		tech->temp1 = el_curlib->lambda[tech->techindex];
21929 	DiaInitTextDialog(dia, DUNO_TECHLIST, us_topoftechlambda, us_nexttechlambda, DiaNullDlogDone, 0,
21930 		SCSELMOUSE|SCREPORT);
21931 	listlen = DiaGetNumScrollLines(dia, DUNO_TECHLIST);
21932 	for(i=0; i<listlen; i++)
21933 	{
21934 		line = DiaGetScrollLine(dia, DUNO_TECHLIST, i);
21935 		for(pt = line; *pt != 0; pt++) if (*pt == ' ') break;
21936 		*pt = 0;
21937 		if (namesame(line, curtech->techname) == 0) break;
21938 	}
21939 	DiaSelectLine(dia, DUNO_TECHLIST, i);
21940 
21941 	/* set the current value of lambda */
21942 	(void)esnprintf(ent, 30, x_("%ld"), curtech->temp1);
21943 	DiaSetText(dia, -DUNO_LAMBDA, ent);
21944 	lambdainmicrons = scaletodispunit(curtech->temp1, DISPUNITMIC);
21945 	(void)esnprintf(ent, 30, x_("(%gu)"), lambdainmicrons);
21946 	DiaSetText(dia, DUNO_MICRONS, ent);
21947 
21948 	/* loop until done */
21949 	toldposlambda = FALSE;
21950 	for(;;)
21951 	{
21952 		itemHit = DiaNextHit(dia);
21953 		if (itemHit == CANCEL) break;
21954 		if (itemHit == OK && DiaValidEntry(dia, DUNO_LAMBDA)) break;
21955 		if (itemHit == DUNO_CHGALLLIBS || itemHit == DUNO_CHGTHISLIB || itemHit == DUNO_CHGNOLIBS)
21956 		{
21957 			DiaSetControl(dia, DUNO_CHGALLLIBS, 0);
21958 			DiaSetControl(dia, DUNO_CHGTHISLIB, 0);
21959 			DiaSetControl(dia, DUNO_CHGNOLIBS, 0);
21960 			DiaSetControl(dia, itemHit, 1);
21961 			continue;
21962 		}
21963 		if (itemHit == DUNO_LAMBDA)
21964 		{
21965 			i = eatoi(DiaGetText(dia, DUNO_LAMBDA));
21966 			if (i <= 0 && !toldposlambda)
21967 			{
21968 				toldposlambda = TRUE;
21969 				DiaMessageInDialog(_("Lambda value must be positive"));
21970 			}
21971 			curtech->temp1 = i;
21972 			lambdainmicrons = scaletodispunit(curtech->temp1, DISPUNITMIC);
21973 			(void)esnprintf(ent, 30, x_("(%gu)"), lambdainmicrons);
21974 			DiaSetText(dia, DUNO_MICRONS, ent);
21975 			which = DiaGetCurLine(dia, DUNO_TECHLIST);
21976 			infstr = initinfstr();
21977 			lambdainmicrons = scaletodispunit(curtech->temp1, DISPUNITMIC);
21978 			formatinfstr(infstr, x_("%s (lambda=%ld, %gu)"), curtech->techname, curtech->temp1,
21979 				lambdainmicrons);
21980 			DiaSetScrollLine(dia, DUNO_TECHLIST, which, returninfstr(infstr));
21981 			continue;
21982 		}
21983 		if (itemHit == DUNO_TECHLIST)
21984 		{
21985 			which = DiaGetCurLine(dia, DUNO_TECHLIST);
21986 			line = DiaGetScrollLine(dia, DUNO_TECHLIST, which);
21987 			for(pt = line; *pt != 0; pt++) if (*pt == ' ') break;
21988 			*pt = 0;
21989 			for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
21990 				if (namesame(line, tech->techname) == 0) break;
21991 			*pt = ' ';
21992 			if (tech == NOTECHNOLOGY) continue;
21993 			curtech = tech;
21994 			(void)esnprintf(ent, 30, x_("%ld"), curtech->temp1);
21995 			DiaSetText(dia, -DUNO_LAMBDA, ent);
21996 			lambdainmicrons = scaletodispunit(curtech->temp1, DISPUNITMIC);
21997 			(void)esnprintf(ent, 30, x_("(%gu)"), lambdainmicrons);
21998 			DiaSetText(dia, DUNO_MICRONS, ent);
21999 			continue;
22000 		}
22001 	}
22002 
22003 	if (itemHit != CANCEL)
22004 	{
22005 		/* set display units */
22006 		i = DiaGetPopupEntry(dia, DUNO_DISTDUNIT);
22007 		switch (i)
22008 		{
22009 			case 0:  newdunit = DISPUNITLAMBDA;  break;
22010 			case 1:  newdunit = DISPUNITINCH;    break;
22011 			case 2:  newdunit = DISPUNITCM;      break;
22012 			case 3:  newdunit = DISPUNITMM;      break;
22013 			case 4:  newdunit = DISPUNITMIL;     break;
22014 			case 5:  newdunit = DISPUNITMIC;     break;
22015 			case 6:  newdunit = DISPUNITCMIC;    break;
22016 			case 7:  newdunit = DISPUNITNM;      break;
22017 			default: newdunit = DISPUNITLAMBDA;  break;
22018 		}
22019 		if (newdunit != olddunit)
22020 			setvalkey((INTBIG)us_tool, VTOOL, us_displayunitskey, newdunit, VINTEGER);
22021 
22022 		/* set other display units if they changed */
22023 		newiunit = 0;
22024 		i = DiaGetPopupEntry(dia, DUNO_RESDUNIT);
22025 		newiunit |= i << INTERNALRESUNITSSH;
22026 		i = DiaGetPopupEntry(dia, DUNO_CAPDUNIT);
22027 		newiunit |= (i << INTERNALCAPUNITSSH);
22028 		i = DiaGetPopupEntry(dia, DUNO_INDDUNIT);
22029 		newiunit |= i << INTERNALINDUNITSSH;
22030 		i = DiaGetPopupEntry(dia, DUNO_CURDUNIT);
22031 		newiunit |= i << INTERNALCURUNITSSH;
22032 		i = DiaGetPopupEntry(dia, DUNO_VOLTDUNIT);
22033 		newiunit |= i << INTERNALVOLTUNITSSH;
22034 		i = DiaGetPopupEntry(dia, DUNO_TIMEDUNIT);
22035 		newiunit |= i << INTERNALTIMEUNITSSH;
22036 		if (newiunit != us_electricalunits)
22037 		{
22038 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_electricalunitskey,
22039 				newiunit, VINTEGER);
22040 
22041 			/* redisplay windows to ensure units look right */
22042 			us_pushhighlight();
22043 			us_clearhighlightcount();
22044 			for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
22045 				if (w->redisphandler != 0) (*w->redisphandler)(w);
22046 			us_pophighlight(FALSE);
22047 		}
22048 		/* see if internal unit was changed */
22049 		i = DiaGetPopupEntry(dia, DUNO_DISTIUNIT);
22050 		switch (i)
22051 		{
22052 			case 0: newiunit = INTUNITHNM;     break;
22053 			case 1: newiunit = INTUNITHDMIC;   break;
22054 		}
22055 		if (newiunit != oldiunit)
22056 			changeinternalunits(NOLIBRARY, el_units, newiunit);
22057 
22058 		/* see if lambda values changed */
22059 		count = 0;
22060 		for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
22061 		{
22062 			if (tech->temp1 <= 0)
22063 				tech->temp1 = el_curlib->lambda[tech->techindex];
22064 			if (tech->temp1 != el_curlib->lambda[tech->techindex]) count++;
22065 		}
22066 		if (count != 0)
22067 		{
22068 			dochange = TRUE;
22069 			if (DiaGetControl(dia, DUNO_CHGALLLIBS) != 0)
22070 			{
22071 				/* changing all libraries */
22072 				i = us_noyesdlog(_("This will scale all of your circuitry, making it potentially incompatible with other libraries.  Continue?"),
22073 					newlang);
22074 				if (i == 0 || namesame(newlang[0], x_("no")) == 0) dochange = FALSE;
22075 				i = 2;
22076 			} else if (DiaGetControl(dia, DUNO_CHGTHISLIB) != 0)
22077 			{
22078 				/* changing only the current library */
22079 				if (el_curlib->nextlibrary == NOLIBRARY)
22080 				{
22081 					i = us_noyesdlog(_("This will scale your circuitry, making it potentially incompatible with other libraries.  Continue?"),
22082 						newlang);
22083 				} else
22084 				{
22085 					i = us_noyesdlog(_("This will scale the circuitry in the current library, making it potentially incompatible with other libraries.  Continue?"),
22086 						newlang);
22087 				}
22088 				if (i == 0 || namesame(newlang[0], x_("no")) == 0) dochange = FALSE;
22089 				i = 1;
22090 			} else
22091 			{
22092 				/* changing no libraries */
22093 				i = us_noyesdlog(_("This will scale the technology primitives, making them potentially incompatible with existing circuitry.  Continue?"),
22094 					newlang);
22095 				if (i == 0 || namesame(newlang[0], x_("no")) == 0) dochange = FALSE;
22096 				i = 0;
22097 			}
22098 
22099 			if (dochange)
22100 			{
22101 				techarray = (TECHNOLOGY **)emalloc(count * (sizeof (TECHNOLOGY *)), el_tempcluster);
22102 				if (techarray == 0) return(0);
22103 				newlamarray = (INTBIG *)emalloc(count * SIZEOFINTBIG, el_tempcluster);
22104 				if (newlamarray == 0) return(0);
22105 				count = 0;
22106 				for(tech = el_technologies; tech != NOTECHNOLOGY; tech = tech->nexttechnology)
22107 				{
22108 					if (tech->temp1 == el_curlib->lambda[tech->techindex]) continue;
22109 					techarray[count] = tech;
22110 					newlamarray[count] = tech->temp1;
22111 					count++;
22112 				}
22113 				oldlam = el_curlib->lambda[el_curtech->techindex];
22114 				newlam = el_curtech->temp1;
22115 
22116 				/* save highlighting */
22117 				us_pushhighlight();
22118 				us_clearhighlightcount();
22119 
22120 				changelambda(count, techarray, newlamarray, el_curlib, i);
22121 				us_setlambda(NOWINDOWFRAME);
22122 				for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
22123 				{
22124 					if (w->curnodeproto == NONODEPROTO) continue;
22125 					if (w->curnodeproto->tech != el_curtech) continue;
22126 					if (i == 2 || (i == 1 && w->curnodeproto->lib == el_curlib))
22127 					{
22128 						w->screenlx = muldiv(w->screenlx, newlam, oldlam);
22129 						w->screenhx = muldiv(w->screenhx, newlam, oldlam);
22130 						w->screenly = muldiv(w->screenly, newlam, oldlam);
22131 						w->screenhy = muldiv(w->screenhy, newlam, oldlam);
22132 						computewindowscale(w);
22133 					} else us_redisplay(w);
22134 				}
22135 
22136 				/* restore highlighting */
22137 				us_pophighlight(FALSE);
22138 				efree((CHAR *)techarray);
22139 				efree((CHAR *)newlamarray);
22140 			}
22141 		}
22142 	}
22143 	DiaDoneDialog(dia);
22144 	return(0);
22145 }
22146 
22147 static TECHNOLOGY *us_curtechlambda;
22148 
us_topoftechlambda(CHAR ** c)22149 BOOLEAN us_topoftechlambda(CHAR **c)
22150 {
22151 	Q_UNUSED( c );
22152 	us_curtechlambda = el_technologies;
22153 	return(TRUE);
22154 }
22155 
us_nexttechlambda(void)22156 CHAR *us_nexttechlambda(void)
22157 {
22158 	float lambdainmicrons;
22159 	REGISTER TECHNOLOGY *tech;
22160 	REGISTER void *infstr;
22161 
22162 	for(;;)
22163 	{
22164 		if (us_curtechlambda == NOTECHNOLOGY) return(0);
22165 		tech = us_curtechlambda;
22166 		us_curtechlambda = us_curtechlambda->nexttechnology;
22167 		if (tech != sch_tech && tech != art_tech && tech != gen_tech) break;
22168 	}
22169 	infstr = initinfstr();
22170 	lambdainmicrons = scaletodispunit(tech->temp1, DISPUNITMIC);
22171 	formatinfstr(infstr, x_("%s (lambda=%ld, %gu)"), tech->techname,
22172 		tech->temp1, lambdainmicrons);
22173 	return(returninfstr(infstr));
22174 }
22175 
22176 /* Prompt: different electrical unit */
22177 static DIALOGITEM us_elecunitdialogitems[] =
22178 {
22179  /*  1 */ {0, {208,212,232,352}, BUTTON, N_("Use new units")},
22180  /*  2 */ {0, {208,20,232,160}, BUTTON, N_("Use former units")},
22181  /*  3 */ {0, {8,8,24,276}, MESSAGE, N_("Warning: displayed units have changed")},
22182  /*  4 */ {0, {36,8,52,108}, MESSAGE, N_("Formerly:")},
22183  /*  5 */ {0, {36,200,52,358}, MESSAGE, N_("New library:")},
22184  /*  6 */ {0, {60,16,76,166}, MESSAGE, x_("")},
22185  /*  7 */ {0, {60,208,76,358}, MESSAGE, x_("")},
22186  /*  8 */ {0, {84,16,100,166}, MESSAGE, x_("")},
22187  /*  9 */ {0, {84,208,100,358}, MESSAGE, x_("")},
22188  /* 10 */ {0, {108,16,124,166}, MESSAGE, x_("")},
22189  /* 11 */ {0, {108,208,124,358}, MESSAGE, x_("")},
22190  /* 12 */ {0, {132,16,148,166}, MESSAGE, x_("")},
22191  /* 13 */ {0, {132,208,148,358}, MESSAGE, x_("")},
22192  /* 14 */ {0, {156,16,172,166}, MESSAGE, x_("")},
22193  /* 15 */ {0, {156,208,172,358}, MESSAGE, x_("")},
22194  /* 16 */ {0, {180,16,196,166}, MESSAGE, x_("")},
22195  /* 17 */ {0, {180,208,196,358}, MESSAGE, x_("")},
22196  /* 18 */ {0, {60,168,76,204}, MESSAGE, x_("")},
22197  /* 19 */ {0, {84,168,100,204}, MESSAGE, x_("")},
22198  /* 20 */ {0, {108,168,124,204}, MESSAGE, x_("")},
22199  /* 21 */ {0, {132,168,148,204}, MESSAGE, x_("")},
22200  /* 22 */ {0, {156,168,172,204}, MESSAGE, x_("")},
22201  /* 23 */ {0, {180,168,196,204}, MESSAGE, x_("")}
22202 };
22203 static DIALOG us_elecunitdialog = {{75,75,316,442}, 0, 0, 23, us_elecunitdialogitems, 0, 0};
22204 
22205 #define DAEU_USENEW       1		/* use new units (button) */
22206 #define DAEU_OLDNEW       2		/* use old units (button) */
22207 #define DAEU_NEWLIBNAME   5		/* new library name (stat text) */
22208 #define DAEU_OLDRES       6		/* old resistance unit (stat text) */
22209 #define DAEU_NEWRES       7		/* new resistance unit (stat text) */
22210 #define DAEU_OLDCAP       8		/* old capacitance unit (stat text) */
22211 #define DAEU_NEWCAP       9		/* new capacitance unit (stat text) */
22212 #define DAEU_OLDIND      10		/* old inductance unit (stat text) */
22213 #define DAEU_NEWIND      11		/* new inductance unit (stat text) */
22214 #define DAEU_OLDCUR      12		/* old current unit (stat text) */
22215 #define DAEU_NEWCUR      13		/* new current unit (stat text) */
22216 #define DAEU_OLDVOLT     14		/* old voltage unit (stat text) */
22217 #define DAEU_NEWVOLT     15		/* new voltage unit (stat text) */
22218 #define DAEU_OLDTIME     16		/* old time unit (stat text) */
22219 #define DAEU_NEWTIME     17		/* new time unit (stat text) */
22220 #define DAEU_DIFFRES     18		/* if resistance units differ (stat text) */
22221 #define DAEU_DIFFCAP     19		/* if capacitance units differ (stat text) */
22222 #define DAEU_DIFFIND     20		/* if inductance units differ (stat text) */
22223 #define DAEU_DIFFCUR     21		/* if current units differ (stat text) */
22224 #define DAEU_DIFFVOLT    22		/* if voltage units differ (stat text) */
22225 #define DAEU_DIFFTIME    23		/* if time units differ (stat text) */
22226 
22227 /*
22228  * Routine to warn that the electrical units have changed, and one set should be chosen.
22229  */
us_adjustelectricalunits(LIBRARY * lib,INTBIG newunits)22230 void us_adjustelectricalunits(LIBRARY *lib, INTBIG newunits)
22231 {
22232 	REGISTER INTBIG itemHit;
22233 	void *infstr;
22234 	REGISTER void *dia;
22235 
22236 	dia = DiaInitDialog(&us_elecunitdialog);
22237 	if (dia == 0) return;
22238 	infstr = initinfstr();
22239 	formatinfstr(infstr, x_("Library %s:"), lib->libname);
22240 	DiaSetText(dia, DAEU_NEWLIBNAME, returninfstr(infstr));
22241 	DiaSetText(dia, DAEU_OLDRES,
22242 		TRANSLATE(us_resistancenames[(us_electricalunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH]));
22243 	DiaSetText(dia, DAEU_NEWRES,
22244 		TRANSLATE(us_resistancenames[(newunits&INTERNALRESUNITS) >> INTERNALRESUNITSSH]));
22245 	if ((us_electricalunits&INTERNALRESUNITS) != (newunits&INTERNALRESUNITS))
22246 		DiaSetText(dia, DAEU_DIFFRES, x_("<-->"));
22247 
22248 	DiaSetText(dia, DAEU_OLDCAP,
22249 		TRANSLATE(us_capacitancenames[(us_electricalunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH]));
22250 	DiaSetText(dia, DAEU_NEWCAP,
22251 		TRANSLATE(us_capacitancenames[(newunits&INTERNALCAPUNITS) >> INTERNALCAPUNITSSH]));
22252 	if ((us_electricalunits&INTERNALCAPUNITS) != (newunits&INTERNALCAPUNITS))
22253 		DiaSetText(dia, DAEU_DIFFCAP, x_("<-->"));
22254 
22255 	DiaSetText(dia, DAEU_OLDIND,
22256 		TRANSLATE(us_inductancenames[(us_electricalunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH]));
22257 	DiaSetText(dia, DAEU_NEWIND,
22258 		TRANSLATE(us_inductancenames[(newunits&INTERNALINDUNITS) >> INTERNALINDUNITSSH]));
22259 	if ((us_electricalunits&INTERNALINDUNITS) != (newunits&INTERNALINDUNITS))
22260 		DiaSetText(dia, DAEU_DIFFIND, x_("<-->"));
22261 
22262 	DiaSetText(dia, DAEU_OLDCUR,
22263 		TRANSLATE(us_currentnames[(us_electricalunits&INTERNALCURUNITS) >> INTERNALCURUNITSSH]));
22264 	DiaSetText(dia, DAEU_NEWCUR,
22265 		TRANSLATE(us_currentnames[(newunits&INTERNALCURUNITS) >> INTERNALCURUNITSSH]));
22266 	if ((us_electricalunits&INTERNALCURUNITS) != (newunits&INTERNALCURUNITS))
22267 		DiaSetText(dia, DAEU_DIFFCUR, x_("<-->"));
22268 
22269 	DiaSetText(dia, DAEU_OLDVOLT,
22270 		TRANSLATE(us_voltagenames[(us_electricalunits&INTERNALVOLTUNITS) >> INTERNALVOLTUNITSSH]));
22271 	DiaSetText(dia, DAEU_NEWVOLT,
22272 		TRANSLATE(us_voltagenames[(newunits&INTERNALVOLTUNITS) >> INTERNALVOLTUNITSSH]));
22273 	if ((us_electricalunits&INTERNALVOLTUNITS) != (newunits&INTERNALVOLTUNITS))
22274 		DiaSetText(dia, DAEU_DIFFVOLT, x_("<-->"));
22275 
22276 	DiaSetText(dia, DAEU_OLDTIME,
22277 		TRANSLATE(us_timenames[(us_electricalunits&INTERNALTIMEUNITS) >> INTERNALTIMEUNITSSH]));
22278 	DiaSetText(dia, DAEU_NEWTIME,
22279 		TRANSLATE(us_timenames[(newunits&INTERNALTIMEUNITS) >> INTERNALTIMEUNITSSH]));
22280 	if ((us_electricalunits&INTERNALTIMEUNITS) != (newunits&INTERNALTIMEUNITS))
22281 		DiaSetText(dia, DAEU_DIFFTIME, x_("<-->"));
22282 	for(;;)
22283 	{
22284 		itemHit = DiaNextHit(dia);
22285 		if (itemHit == DAEU_USENEW || itemHit == DAEU_OLDNEW) break;
22286 	}
22287 	if (itemHit == DAEU_USENEW)
22288 	{
22289 		us_electricalunits = newunits;
22290 		nextchangequiet();
22291 		setvalkey((INTBIG)us_tool, VTOOL, us_electricalunitskey, us_electricalunits, VINTEGER);
22292 	}
22293 	DiaDoneDialog(dia);
22294 }
22295 
22296 /****************************** VARIABLES DIALOG ******************************/
22297 
22298 /* Variables */
22299 static DIALOGITEM us_variabledialogitems[] =
22300 {
22301  /*  1 */ {0, {408,344,432,400}, BUTTON, N_("OK")},
22302  /*  2 */ {0, {352,8,368,56}, MESSAGE, N_("Value:")},
22303  /*  3 */ {0, {336,8,337,408}, DIVIDELINE, x_("")},
22304  /*  4 */ {0, {24,8,40,64}, MESSAGE, N_("Object:")},
22305  /*  5 */ {0, {8,80,24,240}, RADIO, N_("Currently Highlighted")},
22306  /*  6 */ {0, {56,256,72,408}, RADIO, N_("Current Constraint")},
22307  /*  7 */ {0, {24,80,40,240}, RADIO, N_("Current Cell")},
22308  /*  8 */ {0, {40,80,56,240}, RADIO, N_("Current Library")},
22309  /*  9 */ {0, {8,256,24,408}, RADIO, N_("Current Technology")},
22310  /* 10 */ {0, {24,256,40,408}, RADIO, N_("Current Tool")},
22311  /* 11 */ {0, {144,24,160,96}, MESSAGE, N_("Attribute:")},
22312  /* 12 */ {0, {160,8,304,184}, SCROLL, x_("")},
22313  /* 13 */ {0, {312,32,328,152}, CHECK, N_("New Attribute:")},
22314  /* 14 */ {0, {312,160,328,400}, EDITTEXT, x_("")},
22315  /* 15 */ {0, {216,192,232,251}, CHECK, N_("Array")},
22316  /* 16 */ {0, {240,200,256,248}, MESSAGE, N_("Index:")},
22317  /* 17 */ {0, {240,250,256,312}, EDITTEXT, x_("")},
22318  /* 18 */ {0, {408,192,432,296}, BUTTON, N_("Set Attribute")},
22319  /* 19 */ {0, {344,80,376,400}, EDITTEXT, x_("")},
22320  /* 20 */ {0, {408,24,432,144}, BUTTON, N_("Delete Attribute")},
22321  /* 21 */ {0, {168,192,184,288}, CHECK, N_("Displayable")},
22322  /* 22 */ {0, {192,192,208,288}, CHECK, N_("Temporary")},
22323  /* 23 */ {0, {276,224,300,361}, BUTTON, N_("Examine Attribute")},
22324  /* 24 */ {0, {112,40,128,80}, MESSAGE, N_("Type:")},
22325  /* 25 */ {0, {112,80,128,216}, MESSAGE, x_("")},
22326  /* 26 */ {0, {144,184,160,224}, MESSAGE, N_("Type:")},
22327  /* 27 */ {0, {144,224,160,383}, MESSAGE, x_("")},
22328  /* 28 */ {0, {136,8,137,408}, DIVIDELINE, x_("")},
22329  /* 29 */ {0, {80,80,112,408}, MESSAGE, x_("")},
22330  /* 30 */ {0, {80,32,96,80}, MESSAGE, N_("Name:")},
22331  /* 31 */ {0, {168,304,184,410}, POPUP, x_("")},
22332  /* 32 */ {0, {384,80,400,160}, MESSAGE, N_("Evaluation:")},
22333  /* 33 */ {0, {384,160,400,400}, MESSAGE, x_("")},
22334  /* 34 */ {0, {232,320,248,366}, BUTTON, N_("Next")},
22335  /* 35 */ {0, {248,320,264,366}, BUTTON, N_("Prev")},
22336  /* 36 */ {0, {40,256,56,408}, RADIO, N_("Current Window")}
22337 };
22338 static DIALOG us_variabledialog = {{50,75,492,495}, N_("Variable Control"), 0, 36, us_variabledialogitems, 0, 0};
22339 
22340 /* special items for the "variables" dialog: */
22341 #define DVAR_CURHIGHOBJECT  5		/* Currently highlighted object (radio) */
22342 #define DVAR_CURCONSTRAINT  6		/* Current constraint (radio) */
22343 #define DVAR_CURCELL        7		/* Current cell (radio) */
22344 #define DVAR_CURLIB         8		/* Current library (radio) */
22345 #define DVAR_CURTECH        9		/* Current technology (radio) */
22346 #define DVAR_CURTOOL       10		/* Current tool (radio) */
22347 #define DVAR_ATTRLIST      12		/* Attribute name list (scroll) */
22348 #define DVAR_NEWATTR       13		/* New Attribute (check) */
22349 #define DVAR_NEWATTRNAME   14		/* New Attribute name (edit text) */
22350 #define DVAR_ATTRARRAY     15		/* Array attribute (check) */
22351 #define DVAR_ARRAYINDEX_L  16		/* Array index label (stat text) */
22352 #define DVAR_ARRAYINDEX    17		/* Array index (edit text) */
22353 #define DVAR_SETATTR       18		/* Set Attribute (button) */
22354 #define DVAR_ATTRVALUE     19		/* Attribute value (edit text) */
22355 #define DVAR_DELATTR       20		/* Delete Attribute (button) */
22356 #define DVAR_DISPLAYABLE   21		/* Displayable attribute (check) */
22357 #define DVAR_TEMPORARY     22		/* Temporary attribute (check) */
22358 #define DVAR_EXAMINE       23		/* Examine (button) */
22359 #define DVAR_OBJTYPE       25		/* Object type (stat text) */
22360 #define DVAR_ATTRTYPE      27		/* Attribute type (stat text) */
22361 #define DVAR_OBJNAME       29		/* Object name (stat text) */
22362 #define DVAR_LANGUAGE      31		/* Attribute language (popup) */
22363 #define DVAR_EVALUATION_L  32		/* Evaluation label (stat text) */
22364 #define DVAR_EVALUATION    33		/* Evaluation (stat text) */
22365 #define DVAR_NEXTINDEX     34		/* Current constraint (button) */
22366 #define DVAR_PREVINDEX     35		/* Current constraint (button) */
22367 #define DVAR_CURWINDOW     36		/* Current window (radio) */
22368 
22369 static INTBIG    us_possearch, us_varaddr, us_curvaraddr;
22370 static INTBIG    us_vartype, us_curvartype, us_varlength;
22371 static VARIABLE *us_variablesvar;
22372 
22373 static BOOLEAN us_topofdlgvars(CHAR**);
22374 static CHAR   *us_nextdlgvars(void);
22375 static void   us_varestablish(INTBIG, INTBIG, CHAR*, void*);
22376 static void   us_varidentify(void *dia);
22377 
us_topofdlgvars(CHAR ** c)22378 BOOLEAN us_topofdlgvars(CHAR **c)
22379 {
22380 	Q_UNUSED( c );
22381 	us_possearch = initobjlist(us_varaddr, us_vartype, FALSE);
22382 	return(TRUE);
22383 }
us_nextdlgvars(void)22384 CHAR *us_nextdlgvars(void)
22385 {
22386 	VARIABLE *var;
22387 
22388 	return(nextobjectlist(&var, us_possearch));
22389 }
22390 
us_variablesdlog(void)22391 INTBIG us_variablesdlog(void)
22392 {
22393 	INTBIG itemHit, i, j, which, newtype, newaddr;
22394 	UINTBIG descript[TEXTDESCRIPTSIZE];
22395 	REGISTER INTBIG search, newval, *newarray, oldlen;
22396 	CHAR *varname, *name, *newstr, line[100], **languages;
22397 	HIGHLIGHT high;
22398 	REGISTER GEOM *geom;
22399 	VARIABLE *var;
22400 	NODEPROTO *curcell;
22401 	REGISTER void *dia;
22402 	static CHAR nullstr[] = {x_("")};
22403 
22404 	/* display the variables dialog box */
22405 	dia = DiaInitDialog(&us_variabledialog);
22406 	if (dia == 0) return(0);
22407 	languages = us_languagechoices();
22408 	DiaSetPopup(dia, DVAR_LANGUAGE, 4, languages);
22409 	DiaNoEditControl(dia, DVAR_NEWATTRNAME);
22410 	DiaNoEditControl(dia, DVAR_ARRAYINDEX);
22411 
22412 	/* presume the current cell or library */
22413 	curcell = getcurcell();
22414 	us_varaddr = (INTBIG)curcell;
22415 	us_vartype = VNODEPROTO;
22416 	if (curcell == NONODEPROTO)
22417 	{
22418 		/* no current cell: cannot select cell */
22419 		DiaDimItem(dia, DVAR_CURCELL);
22420 		us_varaddr = (INTBIG)el_curlib;
22421 		us_vartype = VLIBRARY;
22422 	} else
22423 	{
22424 		DiaUnDimItem(dia, DVAR_CURCELL);
22425 	}
22426 
22427 	/* see if a single object is highlighted */
22428 	us_curvaraddr = 0;
22429 	us_curvartype = VUNKNOWN;
22430 	var = getvalkey((INTBIG)us_tool, VTOOL, VSTRING|VISARRAY, us_highlightedkey);
22431 	if (var != NOVARIABLE)
22432 	{
22433 		if (getlength(var) == 1)
22434 		{
22435 			if (!us_makehighlight(((CHAR **)var->addr)[0], &high))
22436 			{
22437 				if ((high.status&HIGHTYPE) == HIGHFROM)
22438 				{
22439 					if (!high.fromgeom->entryisnode) us_vartype = VARCINST; else
22440 						us_vartype = VNODEINST;
22441 					us_curvaraddr = us_varaddr = (INTBIG)high.fromgeom->entryaddr.blind;
22442 					us_curvartype = us_vartype;
22443 				}
22444 			}
22445 		}
22446 	}
22447 	if (us_vartype == VNODEPROTO || us_vartype == VLIBRARY)
22448 		DiaDimItem(dia, DVAR_CURHIGHOBJECT); else
22449 			DiaUnDimItem(dia, DVAR_CURHIGHOBJECT);
22450 
22451 	/* initialize the attribute list */
22452 	DiaInitTextDialog(dia, DVAR_ATTRLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1,
22453 		SCSELMOUSE|SCREPORT);
22454 	us_varestablish(us_varaddr, us_vartype, x_(""), dia);
22455 
22456 	/* loop until done */
22457 	for(;;)
22458 	{
22459 		itemHit = DiaNextHit(dia);
22460 		if (itemHit == OK || itemHit == DVAR_SETATTR ||
22461 			itemHit == DVAR_DELATTR || itemHit == CANCEL) break;
22462 		if (itemHit == DVAR_ATTRLIST)
22463 		{
22464 			/* select a new attribute name */
22465 			us_varidentify(dia);
22466 			continue;
22467 		}
22468 		if (itemHit == DVAR_NEWATTR)
22469 		{
22470 			/* want a new variable */
22471 			DiaSetText(dia, DVAR_NEWATTRNAME, x_(""));
22472 			i = DiaGetControl(dia, DVAR_NEWATTR);
22473 			DiaSetControl(dia, DVAR_NEWATTR, 1-i);
22474 			if (i != 0) DiaNoEditControl(dia, DVAR_NEWATTRNAME); else
22475 				DiaEditControl(dia, DVAR_NEWATTRNAME);
22476 			DiaSetText(dia, DVAR_ATTRVALUE, x_(""));
22477 			DiaSetText(dia, -DVAR_NEWATTRNAME, x_(""));
22478 			DiaUnDimItem(dia, DVAR_ATTRARRAY);
22479 			DiaUnDimItem(dia, DVAR_DISPLAYABLE);
22480 			DiaUnDimItem(dia, DVAR_TEMPORARY);
22481 			DiaUnDimItem(dia, DVAR_LANGUAGE);
22482 			DiaDimItem(dia, DVAR_EXAMINE);
22483 			DiaDimItem(dia, DVAR_DELATTR);
22484 			DiaUnDimItem(dia, DVAR_SETATTR);
22485 			continue;
22486 		}
22487 		if (itemHit == DVAR_EXAMINE)
22488 		{
22489 			/* examine the variable */
22490 			which = DiaGetCurLine(dia, DVAR_ATTRLIST);
22491 			if (which < 0) continue;
22492 			varname = DiaGetScrollLine(dia, DVAR_ATTRLIST, which);
22493 			search = initobjlist(us_varaddr, us_vartype, FALSE);
22494 			for(;;)
22495 			{
22496 				name = nextobjectlist(&var, search);
22497 				if (name == 0) break;
22498 				if (estrcmp(name, varname) == 0)
22499 				{
22500 					if ((var->type&VISARRAY) != 0)
22501 					{
22502 						i = myatoi(DiaGetText(dia, DVAR_ARRAYINDEX));
22503 						if (i < 0) i = 0;
22504 						if (i > getlength(var)) i = getlength(var)-1;
22505 						(void)esnprintf(line, 100, x_("%s[%ld]"), varname, i);
22506 						us_varestablish(((INTBIG *)var->addr)[i], var->type&VTYPE, line, dia);
22507 					} else us_varestablish(var->addr, var->type&VTYPE, varname, dia);
22508 					break;
22509 				}
22510 			}
22511 			continue;
22512 		}
22513 		if (itemHit == DVAR_ARRAYINDEX)
22514 		{
22515 			/* changing index */
22516 			if (DiaGetControl(dia, DVAR_NEWATTR) != 0) continue;
22517 			i = myatoi(DiaGetText(dia, DVAR_ARRAYINDEX));
22518 			if (i < 0) i = 0;
22519 			if (i > 0 && i >= us_varlength)
22520 			{
22521 				i = us_varlength-1;
22522 				(void)esnprintf(line, 100, x_("%ld"), i);
22523 				DiaSetText(dia, DVAR_ARRAYINDEX, line);
22524 			}
22525 			DiaSetText(dia, DVAR_ATTRVALUE, describevariable(us_variablesvar, i, -1));
22526 			continue;
22527 		}
22528 		if (itemHit == DVAR_NEXTINDEX)
22529 		{
22530 			/* increment index */
22531 			i = myatoi(DiaGetText(dia, DVAR_ARRAYINDEX)) + 1;
22532 			if (DiaGetControl(dia, DVAR_NEWATTR) == 0)
22533 			{
22534 				if (i >= us_varlength) i = us_varlength-1;
22535 			}
22536 			(void)esnprintf(line, 100, _("%ld"), i);
22537 			DiaSetText(dia, DVAR_ARRAYINDEX, line);
22538 			if (DiaGetControl(dia, DVAR_NEWATTR) == 0)
22539 				DiaSetText(dia, DVAR_ATTRVALUE, describevariable(us_variablesvar, i, -1));
22540 			continue;
22541 		}
22542 		if (itemHit == DVAR_PREVINDEX)
22543 		{
22544 			/* decrement index */
22545 			i = myatoi(DiaGetText(dia, DVAR_ARRAYINDEX)) - 1;
22546 			if (i < 0) continue;
22547 			(void)esnprintf(line, 100, x_("%ld"), i);
22548 			DiaSetText(dia, DVAR_ARRAYINDEX, line);
22549 			if (DiaGetControl(dia, DVAR_NEWATTR) == 0)
22550 				DiaSetText(dia, DVAR_ATTRVALUE, describevariable(us_variablesvar, i, -1));
22551 			continue;
22552 		}
22553 		if (itemHit == DVAR_CURHIGHOBJECT)
22554 		{
22555 			/* want current object */
22556 			us_varestablish(us_curvaraddr, us_curvartype, x_(""), dia);
22557 			continue;
22558 		}
22559 		if (itemHit == DVAR_CURCELL)
22560 		{
22561 			/* want current cell */
22562 			us_varestablish((INTBIG)curcell, VNODEPROTO, x_(""), dia);
22563 			continue;
22564 		}
22565 		if (itemHit == DVAR_CURLIB)
22566 		{
22567 			/* want current library */
22568 			us_varestablish((INTBIG)el_curlib, VLIBRARY, x_(""), dia);
22569 			continue;
22570 		}
22571 		if (itemHit == DVAR_CURTECH)
22572 		{
22573 			/* want current technology */
22574 			us_varestablish((INTBIG)el_curtech, VTECHNOLOGY, x_(""), dia);
22575 			continue;
22576 		}
22577 		if (itemHit == DVAR_CURTOOL)
22578 		{
22579 			/* want current tool */
22580 			us_varestablish((INTBIG)us_tool, VTOOL, x_(""), dia);
22581 			continue;
22582 		}
22583 		if (itemHit == DVAR_CURWINDOW)
22584 		{
22585 			/* want current window */
22586 			us_varestablish((INTBIG)el_curwindowpart, VWINDOWPART, x_(""), dia);
22587 			continue;
22588 		}
22589 		if (itemHit == DVAR_CURCONSTRAINT)
22590 		{
22591 			/* want current constraint */
22592 			us_varestablish((INTBIG)el_curconstraint, VCONSTRAINT, x_(""), dia);
22593 			continue;
22594 		}
22595 		if (itemHit == DVAR_DISPLAYABLE)
22596 		{
22597 			/* displayable attribute */
22598 			DiaSetControl(dia, DVAR_DISPLAYABLE, 1-DiaGetControl(dia, DVAR_DISPLAYABLE));
22599 			continue;
22600 		}
22601 		if (itemHit == DVAR_TEMPORARY)
22602 		{
22603 			/* temporary attribute */
22604 			DiaSetControl(dia, DVAR_TEMPORARY, 1-DiaGetControl(dia, DVAR_TEMPORARY));
22605 			continue;
22606 		}
22607 		if (itemHit == DVAR_ATTRARRAY)
22608 		{
22609 			/* array attribute */
22610 			i = DiaGetControl(dia, DVAR_ATTRARRAY);
22611 			DiaSetControl(dia, DVAR_ATTRARRAY, 1-i);
22612 			if (i == 0)
22613 			{
22614 				DiaUnDimItem(dia, DVAR_ARRAYINDEX_L);
22615 				DiaUnDimItem(dia, DVAR_ARRAYINDEX);
22616 				DiaUnDimItem(dia, DVAR_NEXTINDEX);
22617 				DiaUnDimItem(dia, DVAR_PREVINDEX);
22618 				DiaEditControl(dia, DVAR_ARRAYINDEX);
22619 				DiaSetText(dia, DVAR_ARRAYINDEX, x_("0"));
22620 			} else
22621 			{
22622 				DiaDimItem(dia, DVAR_ARRAYINDEX_L);
22623 				DiaDimItem(dia, DVAR_ARRAYINDEX);
22624 				DiaDimItem(dia, DVAR_NEXTINDEX);
22625 				DiaDimItem(dia, DVAR_PREVINDEX);
22626 				DiaNoEditControl(dia, DVAR_ARRAYINDEX);
22627 				DiaSetText(dia, DVAR_ARRAYINDEX, x_(""));
22628 			}
22629 			continue;
22630 		}
22631 	}
22632 
22633 	/* handle attribute deletion */
22634 	if (itemHit == DVAR_DELATTR)
22635 	{
22636 		startobjectchange(us_varaddr, us_vartype);
22637 		(void)delvalkey(us_varaddr, us_vartype, us_variablesvar->key);
22638 		endobjectchange(us_varaddr, us_vartype);
22639 	}
22640 
22641 	/* handle attribute setting */
22642 	if (itemHit == DVAR_SETATTR)
22643 	{
22644 		/* initialize object to be changed */
22645 		startobjectchange(us_varaddr, us_vartype);
22646 		if (DiaGetControl(dia, DVAR_CURHIGHOBJECT) != 0)
22647 		{
22648 			us_pushhighlight();
22649 			us_clearhighlightcount();
22650 		}
22651 
22652 		/* get new attribute string */
22653 		newstr = DiaGetText(dia, DVAR_ATTRVALUE);
22654 
22655 		/* determine type of attribute */
22656 		if (DiaGetControl(dia, DVAR_NEWATTR) != 0)
22657 		{
22658 			/* setting new attribute */
22659 			varname = DiaGetText(dia, DVAR_NEWATTRNAME);
22660 			getsimpletype(newstr, &newtype, &newaddr, 0);
22661 			if (DiaGetControl(dia, DVAR_ATTRARRAY) != 0) newtype |= VISARRAY;
22662 		} else
22663 		{
22664 			/* modifying existing attribute */
22665 			which = DiaGetCurLine(dia, DVAR_ATTRLIST);
22666 			if (which >= 0) varname = DiaGetScrollLine(dia, DVAR_ATTRLIST, which); else
22667 				varname = x_("");
22668 			newtype = us_variablesvar->type;
22669 		}
22670 		if (DiaGetControl(dia, DVAR_DISPLAYABLE) != 0) newtype |= VDISPLAY; else
22671 			newtype &= ~VDISPLAY;
22672 		if (DiaGetControl(dia, DVAR_TEMPORARY) != 0) newtype |= VCANTSET; else
22673 			newtype &= ~VCANTSET;
22674 		newtype &= ~(VCODE1 | VCODE2);
22675 		switch (DiaGetPopupEntry(dia, DVAR_LANGUAGE))
22676 		{
22677 			case 1: newtype |= VTCL;    break;
22678 			case 2: newtype |= VLISP;   break;
22679 			case 3: newtype |= VJAVA;   break;
22680 		}
22681 
22682 		/* get proper attribute value */
22683 		newval = (INTBIG)newstr;
22684 		if ((newtype&(VCODE1|VCODE2)) == 0)
22685 		{
22686 			switch (newtype&VTYPE)
22687 			{
22688 				case VINTEGER:
22689 				case VADDRESS:
22690 				case VSHORT:
22691 				case VBOOLEAN:
22692 					newval = myatoi(newstr);
22693 					break;
22694 				case VFRACT:
22695 					newval = atofr(newstr);
22696 					break;
22697 				case VFLOAT:
22698 				case VDOUBLE:
22699 					newval = castint((float)eatof(newstr));
22700 					break;
22701 			}
22702 		}
22703 
22704 		/* set the attribute if valid */
22705 		if (*varname != 0)
22706 		{
22707 			/* see if it is an array attribute */
22708 			if (DiaGetControl(dia, DVAR_ATTRARRAY) != 0)
22709 			{
22710 				/* get the array index, examine former attribute */
22711 				which = myatoi(DiaGetText(dia, DVAR_ARRAYINDEX));
22712 				if (which < 0) which = 0;
22713 				var = getval(us_varaddr, us_vartype, -1, varname);
22714 				if (var == NOVARIABLE)
22715 				{
22716 					/* attribute did not exist: create the array */
22717 					newarray = emalloc(((which+1) * SIZEOFINTBIG), el_tempcluster);
22718 					if (newarray == 0) return(0);
22719 					for(j=0; j<=which; j++) newarray[j] = newval;
22720 					newtype |= VISARRAY | ((which+1)<<VLENGTHSH);
22721 					var = setval(us_varaddr, us_vartype, varname, (INTBIG)newarray, newtype);
22722 					if (var != NOVARIABLE)
22723 					{
22724 						if (us_vartype == VARCINST) geom = ((ARCINST *)us_varaddr)->geom; else
22725 							if (us_vartype == VNODEINST) geom = ((NODEINST *)us_varaddr)->geom; else
22726 								geom = NOGEOM;
22727 						defaulttextdescript(var->textdescript, geom);
22728 					}
22729 					efree((CHAR *)newarray);
22730 				} else if (getlength(var) <= which)
22731 				{
22732 					/* extend existing array attribute */
22733 					oldlen = getlength(var);
22734 					newarray = (INTBIG *)emalloc(((which+1) * SIZEOFINTBIG), el_tempcluster);
22735 					if (newarray == 0) return(0);
22736 					if ((newtype&VTYPE) == VSTRING)
22737 					{
22738 						for(j=0; j<oldlen; j++)
22739 							(void)allocstring((CHAR **)&newarray[j],
22740 								(CHAR *)((INTBIG *)var->addr)[j], el_tempcluster);
22741 						for(j=oldlen; j<which; j++) newarray[j] = (INTBIG)nullstr;
22742 					} else
22743 					{
22744 						for(j=0; j<oldlen; j++) newarray[j] = ((INTBIG *)var->addr)[j];
22745 						for(j=oldlen; j<which; j++) newarray[j] = 0;
22746 					}
22747 					newarray[which] = newval;
22748 					newtype = (newtype & ~VLENGTH) | ((which+1)<<VLENGTHSH);
22749 					(void)setval(us_varaddr, us_vartype, varname, (INTBIG)newarray, newtype);
22750 					if ((newtype&VTYPE) == VSTRING)
22751 						for(j=0; j<oldlen; j++) efree((CHAR *)newarray[j]);
22752 					efree((CHAR *)newarray);
22753 				} else
22754 				{
22755 					/* set a single attribute entry */
22756 					(void)setind(us_varaddr, us_vartype, varname, which, newval);
22757 				}
22758 			} else
22759 			{
22760 				/* setting non-array or code attribute */
22761 				var = getval(us_varaddr, us_vartype, newtype, varname);
22762 				if (var != NOVARIABLE) TDCOPY(descript, var->textdescript); else
22763 				{
22764 					if (us_vartype == VARCINST) geom = ((ARCINST *)us_varaddr)->geom; else
22765 						if (us_vartype == VNODEINST) geom = ((NODEINST *)us_varaddr)->geom; else
22766 							geom = NOGEOM;
22767 					TDCLEAR(descript);
22768 					defaulttextdescript(descript, geom);
22769 				}
22770 				var = setval(us_varaddr, us_vartype, varname, newval, newtype);
22771 				if (var != NOVARIABLE) TDCOPY(var->textdescript, descript);
22772 			}
22773 		}
22774 
22775 		/* finish the change */
22776 		if (DiaGetControl(dia, DVAR_CURHIGHOBJECT) != 0) us_pophighlight(TRUE);
22777 		endobjectchange(us_varaddr, us_vartype);
22778 	}
22779 	DiaDoneDialog(dia);
22780 	return(0);
22781 }
22782 
us_varestablish(INTBIG addr,INTBIG type,CHAR * thisname,void * dia)22783 void us_varestablish(INTBIG addr, INTBIG type, CHAR *thisname, void *dia)
22784 {
22785 	REGISTER void *infstr;
22786 
22787 	/* determine which radio button to set */
22788 	DiaSetControl(dia, DVAR_CURHIGHOBJECT, 0);
22789 	DiaSetControl(dia, DVAR_CURCELL, 0);
22790 	DiaSetControl(dia, DVAR_CURLIB, 0);
22791 	DiaSetControl(dia, DVAR_CURTECH, 0);
22792 	DiaSetControl(dia, DVAR_CURTOOL, 0);
22793 	DiaSetControl(dia, DVAR_CURWINDOW, 0);
22794 	DiaSetControl(dia, DVAR_CURCONSTRAINT, 0);
22795 	if (us_curvaraddr != 0 && addr == us_curvaraddr && type == us_curvartype)
22796 	{
22797 		DiaSetControl(dia, DVAR_CURHIGHOBJECT, 1);
22798 		DiaSetText(dia, DVAR_OBJNAME, x_("~"));
22799 		thisname = x_("");
22800 	} else if (getcurcell() != NONODEPROTO && addr == (INTBIG)getcurcell() && type == VNODEPROTO)
22801 	{
22802 		DiaSetControl(dia, DVAR_CURCELL, 1);
22803 		DiaSetText(dia, DVAR_OBJNAME, x_("cell:~"));
22804 		thisname = x_("");
22805 	} else if (addr == (INTBIG)el_curlib && type == VLIBRARY)
22806 	{
22807 		DiaSetControl(dia, DVAR_CURLIB, 1);
22808 		DiaSetText(dia, DVAR_OBJNAME, x_("lib:~"));
22809 		thisname = x_("");
22810 	} else if (addr == (INTBIG)el_curtech && type == VTECHNOLOGY)
22811 	{
22812 		DiaSetControl(dia, DVAR_CURTECH, 1);
22813 		DiaSetText(dia, DVAR_OBJNAME, x_("tech:~"));
22814 		thisname = x_("");
22815 	} else if (addr == (INTBIG)us_tool && type == VTOOL)
22816 	{
22817 		DiaSetControl(dia, DVAR_CURTOOL, 1);
22818 		DiaSetText(dia, DVAR_OBJNAME, x_("tool:~"));
22819 		thisname = x_("");
22820 	} else if (addr == (INTBIG)el_curwindowpart && type == VWINDOWPART)
22821 	{
22822 		DiaSetControl(dia, DVAR_CURWINDOW, 1);
22823 		DiaSetText(dia, DVAR_OBJNAME, x_("window:~"));
22824 		thisname = x_("");
22825 	} else if (addr == (INTBIG)el_curconstraint && type == VCONSTRAINT)
22826 	{
22827 		DiaSetControl(dia, DVAR_CURCONSTRAINT, 1);
22828 		DiaSetText(dia, DVAR_OBJNAME, x_("constraint:~"));
22829 		thisname = x_("");
22830 	}
22831 
22832 	if (*thisname != 0)
22833 	{
22834 		infstr = initinfstr();
22835 		addstringtoinfstr(infstr, DiaGetText(dia, DVAR_OBJNAME));
22836 		addtoinfstr(infstr, '.');
22837 		addstringtoinfstr(infstr, thisname);
22838 		DiaSetText(dia, DVAR_OBJNAME, returninfstr(infstr));
22839 	}
22840 	us_varaddr = addr;
22841 	us_vartype = type;
22842 	DiaSetText(dia, DVAR_OBJTYPE, us_variabletypename(type));
22843 	DiaLoadTextDialog(dia, DVAR_ATTRLIST, us_topofdlgvars, us_nextdlgvars, DiaNullDlogDone, 0);
22844 	us_varidentify(dia);
22845 }
22846 
us_varidentify(void * dia)22847 void us_varidentify(void *dia)
22848 {
22849 	INTBIG which, aindex, type;
22850 	REGISTER INTBIG search, language;
22851 	CHAR *varname, *name;
22852 	VARIABLE *var;
22853 
22854 	DiaSetControl(dia, DVAR_NEWATTR, 0);
22855 	DiaSetText(dia, DVAR_NEWATTRNAME, x_(""));
22856 	DiaNoEditControl(dia, DVAR_NEWATTRNAME);
22857 	DiaDimItem(dia, DVAR_ATTRARRAY);
22858 	DiaDimItem(dia, DVAR_LANGUAGE);
22859 	DiaDimItem(dia, DVAR_SETATTR);
22860 	DiaDimItem(dia, DVAR_DELATTR);
22861 	DiaDimItem(dia, DVAR_DISPLAYABLE);
22862 	DiaDimItem(dia, DVAR_TEMPORARY);
22863 	DiaDimItem(dia, DVAR_EXAMINE);
22864 	DiaDimItem(dia, DVAR_ARRAYINDEX_L);
22865 	DiaDimItem(dia, DVAR_NEXTINDEX);
22866 	DiaDimItem(dia, DVAR_PREVINDEX);
22867 	which = DiaGetCurLine(dia, DVAR_ATTRLIST);
22868 	if (which < 0) return;
22869 	varname = DiaGetScrollLine(dia, DVAR_ATTRLIST, which);
22870 	search = initobjlist(us_varaddr, us_vartype, FALSE);
22871 	for(;;)
22872 	{
22873 		name = nextobjectlist(&us_variablesvar, search);
22874 		if (name == 0) break;
22875 		if (estrcmp(name, varname) == 0) break;
22876 	}
22877 	if (name == 0) return;
22878 
22879 	us_varlength = getlength(us_variablesvar);
22880 	type = us_variablesvar->type&VTYPE;
22881 	if ((us_variablesvar->type&VCREF) == 0)
22882 	{
22883 		DiaUnDimItem(dia, DVAR_DELATTR);
22884 		DiaUnDimItem(dia, DVAR_DISPLAYABLE);
22885 		DiaUnDimItem(dia, DVAR_TEMPORARY);
22886 		DiaUnDimItem(dia, DVAR_LANGUAGE);
22887 	}
22888 	if ((us_variablesvar->type&VCANTSET) == 0) DiaUnDimItem(dia, DVAR_SETATTR);
22889 	DiaSetText(dia, DVAR_ATTRTYPE, us_variabletypename(type));
22890 	if ((us_variablesvar->type&VDISPLAY) != 0) DiaSetControl(dia, DVAR_DISPLAYABLE, 1); else
22891 		DiaSetControl(dia, DVAR_DISPLAYABLE, 0);
22892 	if ((us_variablesvar->type&VDONTSAVE) != 0) DiaSetControl(dia, DVAR_TEMPORARY, 1); else
22893 		DiaSetControl(dia, DVAR_TEMPORARY, 0);
22894 	language = us_variablesvar->type & (VCODE1|VCODE2);
22895 	switch (language)
22896 	{
22897 		case 0:     DiaSetPopupEntry(dia, DVAR_LANGUAGE, 0);   break;
22898 		case VTCL:  DiaSetPopupEntry(dia, DVAR_LANGUAGE, 1);   break;
22899 		case VLISP: DiaSetPopupEntry(dia, DVAR_LANGUAGE, 2);   break;
22900 		case VJAVA: DiaSetPopupEntry(dia, DVAR_LANGUAGE, 3);   break;
22901 	}
22902 	if ((us_variablesvar->type&VISARRAY) != 0)
22903 	{
22904 		DiaSetControl(dia, DVAR_ATTRARRAY, 1);
22905 		DiaUnDimItem(dia, DVAR_ARRAYINDEX_L);
22906 		DiaUnDimItem(dia, DVAR_NEXTINDEX);
22907 		DiaUnDimItem(dia, DVAR_PREVINDEX);
22908 		DiaSetText(dia, DVAR_ARRAYINDEX, x_("0"));
22909 		DiaEditControl(dia, DVAR_ARRAYINDEX);
22910 		aindex = 0;
22911 	} else
22912 	{
22913 		DiaSetControl(dia, DVAR_ATTRARRAY, 0);
22914 		DiaSetText(dia, DVAR_ARRAYINDEX, x_(""));
22915 		DiaNoEditControl(dia, DVAR_ARRAYINDEX);
22916 		aindex = -1;
22917 	}
22918 	DiaSetText(dia, DVAR_ATTRVALUE, describevariable(us_variablesvar, aindex, -1));
22919 	if (language != 0)
22920 	{
22921 		var = doquerry((CHAR *)us_variablesvar->addr, language, us_variablesvar->type & ~(VCODE1|VCODE2));
22922 		if (var != NOVARIABLE)
22923 			TDCOPY(var->textdescript, us_variablesvar->textdescript);
22924 		DiaSetText(dia, DVAR_EVALUATION, describevariable(var, aindex, -1));
22925 		DiaSetText(dia, DVAR_EVALUATION_L, _("Evaluation:"));
22926 	} else
22927 	{
22928 		DiaSetText(dia, DVAR_EVALUATION, x_(""));
22929 		DiaSetText(dia, DVAR_EVALUATION_L, x_(""));
22930 	}
22931 	if (type != VUNKNOWN && type != VINTEGER && type != VADDRESS && type != VCHAR &&
22932 		type != VSTRING && type != VFLOAT && type != VDOUBLE && type != VFRACT && type != VSHORT && type != VBOOLEAN)
22933 			DiaUnDimItem(dia, DVAR_EXAMINE);
22934 }
22935 
22936 /****************************** VIEW CREATION DIALOG ******************************/
22937 
22938 /* New view */
22939 static DIALOGITEM us_newviewdialogitems[] =
22940 {
22941  /*  1 */ {0, {64,232,88,304}, BUTTON, N_("OK")},
22942  /*  2 */ {0, {64,16,88,88}, BUTTON, N_("Cancel")},
22943  /*  3 */ {0, {8,8,24,145}, MESSAGE, N_("New view name:")},
22944  /*  4 */ {0, {32,8,48,145}, MESSAGE, N_("View abbreviation:")},
22945  /*  5 */ {0, {8,148,24,304}, EDITTEXT, x_("")},
22946  /*  6 */ {0, {32,148,48,304}, EDITTEXT, x_("")},
22947  /*  7 */ {0, {68,104,84,213}, CHECK, N_("Textual View")}
22948 };
22949 static DIALOG us_newviewdialog = {{50,75,154,391}, N_("New View"), 0, 7, us_newviewdialogitems, 0, 0};
22950 
22951 /* special items for the "new view" dialog: */
22952 #define DNVW_VIEWNAME    5		/* New view name (edit text) */
22953 #define DNVW_VIEWABBR    6		/* View abbreviation (edit text) */
22954 #define DNVW_TEXTVIEW    7		/* Textual view (check) */
22955 
us_newviewdlog(CHAR * paramstart[])22956 INTBIG us_newviewdlog(CHAR *paramstart[])
22957 {
22958 	INTBIG itemHit;
22959 	REGISTER void *infstr;
22960 	REGISTER void *dia;
22961 
22962 	/* display the port dialog box */
22963 	dia = DiaInitDialog(&us_newviewdialog);
22964 	if (dia == 0) return(0);
22965 
22966 	/* loop until done */
22967 	for(;;)
22968 	{
22969 		itemHit = DiaNextHit(dia);
22970 		if (itemHit == CANCEL) break;
22971 		if (itemHit == OK && DiaValidEntry(dia, DNVW_VIEWNAME) && DiaValidEntry(dia, DNVW_VIEWABBR)) break;
22972 		if (itemHit == DNVW_TEXTVIEW)
22973 		{
22974 			DiaSetControl(dia, itemHit, 1-DiaGetControl(dia, itemHit));
22975 			continue;
22976 		}
22977 	}
22978 
22979 	paramstart[0] = x_("");
22980 	if (itemHit != CANCEL)
22981 	{
22982 		infstr = initinfstr();
22983 		addstringtoinfstr(infstr, DiaGetText(dia, DNVW_VIEWNAME));
22984 		addtoinfstr(infstr, ' ');
22985 		addstringtoinfstr(infstr, DiaGetText(dia, DNVW_VIEWABBR));
22986 		if (DiaGetControl(dia, DNVW_TEXTVIEW) != 0) addstringtoinfstr(infstr, _(" text"));
22987 		if (us_returneddialogstring != 0) efree((CHAR *)us_returneddialogstring);
22988 		allocstring(&us_returneddialogstring, returninfstr(infstr), us_tool->cluster);
22989 		paramstart[0] = us_returneddialogstring;
22990 	}
22991 	DiaDoneDialog(dia);
22992 	return(1);
22993 }
22994 
22995 /****************************** VIEW SELECTION DIALOG ******************************/
22996 
22997 /* View: Select */
22998 static DIALOGITEM us_viewseldialogitems[] =
22999 {
23000  /*  1 */ {0, {176,108,200,188}, BUTTON, N_("OK")},
23001  /*  2 */ {0, {176,8,200,88}, BUTTON, N_("Cancel")},
23002  /*  3 */ {0, {8,8,168,188}, SCROLL, x_("")}
23003 };
23004 static DIALOG us_viewseldialog = {{75,75,284,272}, N_("Select View"), 0, 3, us_viewseldialogitems, 0, 0};
23005 
23006 /* special items for the "view selection" dialog: */
23007 #define DVSL_VIEWLIST     3		/* View list (scroll) */
23008 
23009 static INTBIG us_viewlistdeleteonly;
23010 static VIEW  *us_posviewcomcomp;
23011 
23012 static BOOLEAN us_diatopofviews(CHAR **c);
23013 static CHAR   *us_dianextviews(void);
23014 
us_diatopofviews(CHAR ** c)23015 BOOLEAN us_diatopofviews(CHAR **c)
23016 {
23017 	Q_UNUSED( c );
23018 	us_posviewcomcomp = el_views;
23019 	return(TRUE);
23020 }
23021 
us_dianextviews(void)23022 CHAR *us_dianextviews(void)
23023 {
23024 	REGISTER VIEW *v;
23025 
23026 	for(;;)
23027 	{
23028 		v = us_posviewcomcomp;
23029 		if (v == NOVIEW) break;
23030 		us_posviewcomcomp = v->nextview;
23031 		if (us_viewlistdeleteonly != 0 &&
23032 			(v->viewstate&PERMANENTVIEW) != 0) continue;
23033 		return(v->viewname);
23034 	}
23035 	return(0);
23036 }
23037 
us_viewdlog(INTBIG deleteview)23038 INTBIG us_viewdlog(INTBIG deleteview)
23039 {
23040 	INTBIG itemHit, i;
23041 	CHAR *arg[3];
23042 	REGISTER void *dia;
23043 
23044 	/* display the port dialog box */
23045 	us_viewlistdeleteonly = deleteview;
23046 	if (deleteview != 0) us_viewseldialog.movable = _("View to Delete"); else
23047 		us_viewseldialog.movable = _("Select View");
23048 	dia = DiaInitDialog(&us_viewseldialog);
23049 	if (dia == 0) return(0);
23050 	DiaInitTextDialog(dia, DVSL_VIEWLIST, us_diatopofviews, us_dianextviews, DiaNullDlogDone, 0,
23051 		SCSELMOUSE);
23052 
23053 	/* loop until done */
23054 	for(;;)
23055 	{
23056 		itemHit = DiaNextHit(dia);
23057 		if (itemHit == CANCEL || itemHit == OK) break;
23058 	}
23059 
23060 	if (itemHit != CANCEL)
23061 	{
23062 		i = DiaGetCurLine(dia, DVSL_VIEWLIST);
23063 		if (i >= 0)
23064 		{
23065 			arg[0] = x_("delete");
23066 			arg[1] = DiaGetScrollLine(dia, DVSL_VIEWLIST, i);
23067 			us_view(2, arg);
23068 		}
23069 	}
23070 	DiaDoneDialog(dia);
23071 	return(1);
23072 }
23073 
23074 /****************************** VISIBLE LAYERS DIALOG ******************************/
23075 
23076 /* Layer Visibility */
23077 static DIALOGITEM us_visiblelaydialogitems[] =
23078 {
23079  /*  1 */ {0, {32,8,208,222}, SCROLL, x_("")},
23080  /*  2 */ {0, {8,8,24,82}, MESSAGE, N_("Layer set:")},
23081  /*  3 */ {0, {8,88,24,294}, POPUP, x_("")},
23082  /*  4 */ {0, {40,230,56,382}, MESSAGE, N_("Text visibility options:")},
23083  /*  5 */ {0, {60,242,76,394}, AUTOCHECK, N_("Node text")},
23084  /*  6 */ {0, {80,242,96,394}, AUTOCHECK, N_("Arc text")},
23085  /*  7 */ {0, {100,242,116,394}, AUTOCHECK, N_("Port text")},
23086  /*  8 */ {0, {120,242,136,394}, AUTOCHECK, N_("Export text")},
23087  /*  9 */ {0, {140,242,156,394}, AUTOCHECK, N_("Nonlayout text")},
23088  /* 10 */ {0, {160,242,176,394}, AUTOCHECK, N_("Instance names")},
23089  /* 11 */ {0, {180,242,196,394}, AUTOCHECK, N_("Cell text")},
23090  /* 12 */ {0, {212,16,228,222}, MESSAGE, N_("Click to change visibility.")},
23091  /* 13 */ {0, {228,16,244,222}, MESSAGE, N_("Marked layers are visible.")},
23092  /* 14 */ {0, {252,8,276,108}, BUTTON, N_("All Visible")},
23093  /* 15 */ {0, {252,122,276,222}, BUTTON, N_("All Invisible")},
23094  /* 16 */ {0, {214,316,238,388}, BUTTON, N_("Done")},
23095  /* 17 */ {0, {250,316,274,388}, DEFBUTTON, N_("Apply")}
23096 };
23097 static DIALOG us_visiblelaydialog = {{50,75,335,479}, N_("Layer Visibility"), 0, 17, us_visiblelaydialogitems, x_("visiblelay"), 0};
23098 
23099 /* special items for the "visiblelay" dialog: */
23100 #define DVSL_LAYERLIST     1		/* Layers (scroll) */
23101 #define DVSL_LAYERSET_L    2		/* Layer set (message) */
23102 #define DVSL_LAYERSET      3		/* Set of layers (popup) */
23103 #define DVSL_OPTIONS_L     4		/* Text visibility options (message) */
23104 #define DVSL_NODETEXT      5		/* Show node text (autocheck) */
23105 #define DVSL_ARCTEXT       6		/* Show arc text (autocheck) */
23106 #define DVSL_PORTTEXT      7		/* Show port text (autocheck) */
23107 #define DVSL_EXPORTTEXT    8		/* Show export text (autocheck) */
23108 #define DVSL_NONLAYTEXT    9		/* Show nonlayout text (autocheck) */
23109 #define DVSL_INSTTEXT     10		/* Show instance text (autocheck) */
23110 #define DVSL_CELLTEXT     11		/* Show cell text (autocheck) */
23111 #define DVSL_CLICK_L      12		/* Click to change (message) */
23112 #define DVSL_MARKED_L     13		/* Marked layers (message) */
23113 #define DVSL_ALLVISIBLE   14		/* Make all visible (button) */
23114 #define DVSL_ALLINVISIBLE 15		/* Make all invisible (button) */
23115 #define DVSL_DONE         16		/* Done (button) */
23116 #define DVSL_APPLY        17		/* Apply (defbutton) */
23117 
23118 #define LAYERSELEC 0		/* Electric layers */
23119 #define LAYERSDXF  1		/* DXF layers */
23120 #define LAYERSGDS  2		/* GDS layers */
23121 
23122 class EDiaVisibleLayer : public EDialogModeless
23123 {
23124 public:
23125 	EDiaVisibleLayer();
23126 	void showLayerSet(CHAR *prompt);
23127 	static EDiaVisibleLayer *dialog;
23128 private:
23129 	BOOLEAN changes;
23130 
23131 	void itemHitAction(INTBIG itemHit);
23132 	void loadSet();
23133 };
23134 
23135 EDiaVisibleLayer *EDiaVisibleLayer::dialog = 0;
23136 
us_visiblelayersdlog(CHAR * prompt)23137 INTBIG us_visiblelayersdlog(CHAR *prompt)
23138 {
23139 
23140 	if (us_needwindow()) return(0);
23141 
23142 	/* display the visibility dialog box */
23143 	if (EDiaVisibleLayer::dialog == 0) EDiaVisibleLayer::dialog = new EDiaVisibleLayer();
23144 	EDiaVisibleLayer::dialog->showLayerSet( prompt );
23145 	return(0);
23146 }
23147 
EDiaVisibleLayer()23148 EDiaVisibleLayer::EDiaVisibleLayer()
23149 	: EDialogModeless(&us_visiblelaydialog)
23150 {
23151 }
23152 
showLayerSet(CHAR * prompt)23153 void EDiaVisibleLayer::showLayerSet( CHAR * prompt )
23154 {
23155 	CHAR *layersets[3];
23156 
23157 	show();
23158 	layersets[LAYERSELEC] = _("Electric layers");
23159 	layersets[LAYERSDXF] = _("DXF layers");
23160 	layersets[LAYERSGDS] = _("GDS layers");
23161 	setPopup(DVSL_LAYERSET, 3, layersets);
23162 	if (namesame(prompt, x_("DXF")) == 0) setPopupEntry(DVSL_LAYERSET, LAYERSDXF); else
23163 		if (namesame(prompt, x_("GDS")) == 0) setPopupEntry(DVSL_LAYERSET, LAYERSGDS);
23164 	initTextDialog(DVSL_LAYERLIST, DiaNullDlogList, DiaNullDlogItem,
23165 		DiaNullDlogDone, -1, SCSELMOUSE|SCREPORT);
23166 	loadSet();
23167 	if ((us_useroptions&HIDETXTNODE)     == 0) setControl(DVSL_NODETEXT, 1);
23168 	if ((us_useroptions&HIDETXTARC)      == 0) setControl(DVSL_ARCTEXT, 1);
23169 	if ((us_useroptions&HIDETXTPORT)     == 0) setControl(DVSL_PORTTEXT, 1);
23170 	if ((us_useroptions&HIDETXTEXPORT)   == 0) setControl(DVSL_EXPORTTEXT, 1);
23171 	if ((us_useroptions&HIDETXTNONLAY)   == 0) setControl(DVSL_NONLAYTEXT, 1);
23172 	if ((us_useroptions&HIDETXTINSTNAME) == 0) setControl(DVSL_INSTTEXT, 1);
23173 	if ((us_useroptions&HIDETXTCELL)    == 0) setControl(DVSL_CELLTEXT, 1);
23174 	changes = FALSE;
23175 }
23176 
23177 /*
23178  * Coroutine to handle hits in the modeless "layer visibility" dialog.
23179  */
itemHitAction(INTBIG itemHit)23180 void EDiaVisibleLayer::itemHitAction(INTBIG itemHit)
23181 {
23182 	INTBIG i, val, layerset, listlen;
23183 	REGISTER NODEINST *ni;
23184 	REGISTER NODEPROTO *np;
23185 	REGISTER VARIABLE *var;
23186 	WINDOWPART *w;
23187 	CHAR *msg, *entry, lnum[20], *lname;
23188 
23189 	if (itemHit == DVSL_DONE)
23190 	{
23191 		hide();
23192 		return;
23193 	}
23194 	if (itemHit == DVSL_LAYERLIST)
23195 	{
23196 		/* toggle layer visibility for this layer */
23197 		i = getCurLine(DVSL_LAYERLIST);
23198 		if (i < 0) return;
23199 		msg = getScrollLine(DVSL_LAYERLIST, i);
23200 		if (*msg == ' ') *msg = '>'; else *msg = ' ';
23201 		setScrollLine(DVSL_LAYERLIST, i, msg);
23202 		changes = TRUE;
23203 		return;
23204 	}
23205 	if (itemHit == DVSL_ALLVISIBLE || itemHit == DVSL_ALLINVISIBLE)
23206 	{
23207 		/* set visibility for all layers */
23208 		listlen = getNumScrollLines(DVSL_LAYERLIST);
23209 		for(i=0; i<listlen; i++)
23210 		{
23211 			msg = getScrollLine(DVSL_LAYERLIST, i);
23212 			if (itemHit == DVSL_ALLVISIBLE) *msg = '>'; else *msg = ' ';
23213 			setScrollLine(DVSL_LAYERLIST, i, msg);
23214 		}
23215 		changes = TRUE;
23216 		return;
23217 	}
23218 	if (itemHit == DVSL_LAYERSET)
23219 	{
23220 		/* construct new layer set */
23221 		loadSet();
23222 		changes = FALSE;
23223 		return;
23224 	}
23225 	if (itemHit == DVSL_APPLY)
23226 	{
23227 		i = us_useroptions;
23228 		if (getControl(DVSL_NODETEXT) != 0) i &= ~HIDETXTNODE; else
23229 			i |= HIDETXTNODE;
23230 		if (getControl(DVSL_ARCTEXT) != 0) i &= ~HIDETXTARC; else
23231 			i |= HIDETXTARC;
23232 		if (getControl(DVSL_PORTTEXT) != 0) i &= ~HIDETXTPORT; else
23233 			i |= HIDETXTPORT;
23234 		if (getControl(DVSL_EXPORTTEXT) != 0) i &= ~HIDETXTEXPORT; else
23235 			i |= HIDETXTEXPORT;
23236 		if (getControl(DVSL_NONLAYTEXT) != 0) i &= ~HIDETXTNONLAY; else
23237 			i |= HIDETXTNONLAY;
23238 		if (getControl(DVSL_INSTTEXT) != 0) i &= ~HIDETXTINSTNAME; else
23239 			i |= HIDETXTINSTNAME;
23240 		if (getControl(DVSL_CELLTEXT) != 0) i &= ~HIDETXTCELL; else
23241 			i |= HIDETXTCELL;
23242 		if (i != us_useroptions)
23243 		{
23244 			startobjectchange((INTBIG)us_tool, VTOOL);
23245 			(void)setvalkey((INTBIG)us_tool, VTOOL, us_optionflagskey, i, VINTEGER);
23246 			endobjectchange((INTBIG)us_tool, VTOOL);
23247 		}
23248 
23249 		if (changes)
23250 		{
23251 			/* save highlighting */
23252 			us_pushhighlight();
23253 
23254 			/* start of change to all display windows */
23255 			for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
23256 				if ((w->state&WINDOWTYPE) == DISPWINDOW ||
23257 					(w->state&WINDOWTYPE) == DISP3DWINDOW)
23258 						startobjectchange((INTBIG)w, VWINDOWPART);
23259 
23260 			layerset = getPopupEntry(DVSL_LAYERSET);
23261 			switch (layerset)
23262 			{
23263 				case LAYERSELEC:
23264 					/* change the layer visibility */
23265 					for(i=0; i<el_curtech->layercount; i++)
23266 					{
23267 						msg = getScrollLine(DVSL_LAYERLIST, i);
23268 						val = el_curtech->layers[i]->colstyle;
23269 						if ((val&INVISIBLE) == 0 && *msg == ' ')
23270 						{
23271 							(void)setval((INTBIG)el_curtech->layers[i], VGRAPHICS,
23272 								x_("colstyle"), val | INVISIBLE, VSHORT);
23273 						} else if ((val&INVISIBLE) != 0 && *msg != ' ')
23274 						{
23275 							(void)setval((INTBIG)el_curtech->layers[i], VGRAPHICS,
23276 								x_("colstyle"), val & ~INVISIBLE, VSHORT);
23277 						}
23278 					}
23279 					break;
23280 				case LAYERSDXF:
23281 				case LAYERSGDS:
23282 					np = getcurcell();
23283 					if (np == NONODEPROTO) break;
23284 					for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
23285 					{
23286 						if (layerset == LAYERSDXF)
23287 						{
23288 							var = getval((INTBIG)ni, VNODEINST, VSTRING, x_("IO_dxf_layer"));
23289 							if (var == NOVARIABLE) continue;
23290 							lname = (CHAR *)var->addr;
23291 						} else
23292 						{
23293 							var = getval((INTBIG)ni, VNODEINST, VINTEGER, x_("IO_gds_layer"));
23294 							if (var == NOVARIABLE) continue;
23295 							esnprintf(lnum, 20, x_("%ld"), var->addr);
23296 							lname = lnum;
23297 						}
23298 						listlen = getNumScrollLines(DVSL_LAYERLIST);
23299 						for(i=0; i<listlen; i++)
23300 						{
23301 							entry = getScrollLine(DVSL_LAYERLIST, i);
23302 							if (namesame(&entry[2], lname) == 0) break;
23303 						}
23304 						if (*entry != 0)
23305 						{
23306 							startobjectchange((INTBIG)ni, VNODEINST);
23307 							if (entry[0] == '>')
23308 							{
23309 								/* make node visible */
23310 								var = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, art_colorkey);
23311 								if (var != NOVARIABLE && var->addr == 0)
23312 									(void)delvalkey((INTBIG)ni, VNODEINST, art_colorkey);
23313 							} else
23314 							{
23315 								/* make node invisible */
23316 								setvalkey((INTBIG)ni, VNODEINST, art_colorkey, 0, VINTEGER);
23317 							}
23318 							endobjectchange((INTBIG)ni, VNODEINST);
23319 						}
23320 					}
23321 					break;
23322 			}
23323 
23324 			/* end of change to all display windows (redraws) */
23325 			for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
23326 				if ((w->state&WINDOWTYPE) == DISPWINDOW ||
23327 					(w->state&WINDOWTYPE) == DISP3DWINDOW)
23328 						endobjectchange((INTBIG)w, VWINDOWPART);
23329 
23330 			/* restore highlighting */
23331 			us_pophighlight(FALSE);
23332 			us_endchanges(NOWINDOWPART);
23333 			flushscreen();
23334 		}
23335 		changes = FALSE;
23336 		return;
23337 	}
23338 }
23339 
23340 /*
23341  * Helper routine for "us_visiblelayersdlog()" to load the layers into the list.
23342  */
loadSet()23343 void EDiaVisibleLayer::loadSet()
23344 {
23345 	REGISTER NODEINST *ni;
23346 	REGISTER NODEPROTO *np;
23347 	REGISTER VARIABLE *var, *cvar;
23348 	REGISTER INTBIG i, layerset, fun, listlen;
23349 	REGISTER CHAR *lname, *entry;
23350 	CHAR lbuff[100], lnum[20];
23351 	REGISTER void *infstr;
23352 
23353 	loadTextDialog(DVSL_LAYERLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0);
23354 	layerset = getPopupEntry(DVSL_LAYERSET);
23355 	switch (layerset)
23356 	{
23357 		case LAYERSELEC:
23358 			for(i=0; i<el_curtech->layercount; i++)
23359 			{
23360 				infstr = initinfstr();
23361 				if ((el_curtech->layers[i]->colstyle&INVISIBLE) != 0) addtoinfstr(infstr, ' '); else
23362 					addtoinfstr(infstr, '>');
23363 				addtoinfstr(infstr, ' ');
23364 				addstringtoinfstr(infstr, layername(el_curtech, i));
23365 				fun = layerfunction(el_curtech, i);
23366 				if ((fun&LFPSEUDO) != 0) addstringtoinfstr(infstr, _(" (for pins)"));
23367 				stuffLine(DVSL_LAYERLIST, returninfstr(infstr));
23368 			}
23369 			break;
23370 		case LAYERSDXF:
23371 		case LAYERSGDS:
23372 			np = getcurcell();
23373 			if (np == NONODEPROTO) break;
23374 			for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
23375 			{
23376 				if (layerset == LAYERSDXF)
23377 				{
23378 					var = getval((INTBIG)ni, VNODEINST, VSTRING, x_("IO_dxf_layer"));
23379 					if (var == NOVARIABLE) continue;
23380 					lname = (CHAR *)var->addr;
23381 				} else
23382 				{
23383 					var = getval((INTBIG)ni, VNODEINST, VINTEGER, x_("IO_gds_layer"));
23384 					if (var == NOVARIABLE) continue;
23385 					esnprintf(lnum, 20, x_("%ld"), var->addr);
23386 					lname = lnum;
23387 				}
23388 				listlen = getNumScrollLines(DVSL_LAYERLIST);
23389 				for(i=0; i<listlen; i++)
23390 				{
23391 					entry = getScrollLine(DVSL_LAYERLIST, i);
23392 					if (namesame(&entry[2], lname) == 0) break;
23393 				}
23394 				if (i >= listlen)
23395 				{
23396 					cvar = getvalkey((INTBIG)ni, VNODEINST, VINTEGER, art_colorkey);
23397 					if (cvar != NOVARIABLE && cvar->addr == 0)
23398 						esnprintf(lbuff, 100, x_("  %s"), lname); else
23399 							esnprintf(lbuff, 100, x_("> %s"), lname);
23400 					stuffLine(DVSL_LAYERLIST, lbuff);
23401 				}
23402 			}
23403 			break;
23404 	}
23405 	selectLine(DVSL_LAYERLIST, -1);
23406 }
23407 
23408 /****************************** WINDOW VIEW DIALOG ******************************/
23409 
23410 /* Window Views */
23411 static DIALOGITEM us_windowviewdialogitems[] =
23412 {
23413  /*  1 */ {0, {256,56,280,166}, BUTTON, N_("Restore View")},
23414  /*  2 */ {0, {216,8,240,72}, BUTTON, N_("Done")},
23415  /*  3 */ {0, {32,8,208,234}, SCROLL, x_("")},
23416  /*  4 */ {0, {8,96,24,229}, EDITTEXT, x_("")},
23417  /*  5 */ {0, {216,120,240,230}, BUTTON, N_("Save This View")},
23418  /*  6 */ {0, {8,8,24,90}, MESSAGE, N_("View name:")}
23419 };
23420 static DIALOG us_windowviewdialog = {{50,75,342,318}, N_("Window Views"), 0, 6, us_windowviewdialogitems, 0, 0};
23421 
23422 /* special items for the "Window View" dialog: */
23423 #define DWNV_RESTOREVIEW  1		/* restore view (button) */
23424 #define DWNV_VIEWLIST     3		/* view list (scroll) */
23425 #define DWNV_VIEWNAME     4		/* new view name (edit text) */
23426 #define DWNV_SAVEVIEW     5		/* save view (button) */
23427 
us_windowviewdlog(void)23428 INTBIG us_windowviewdlog(void)
23429 {
23430 	INTBIG itemHit, i;
23431 	REGISTER VARIABLE *var;
23432 	CHAR *par[3], *pt;
23433 	REGISTER void *dia;
23434 
23435 	/* display the window view dialog box */
23436 	dia = DiaInitDialog(&us_windowviewdialog);
23437 	if (dia == 0) return(0);
23438 	DiaInitTextDialog(dia, DWNV_VIEWLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
23439 		SCSELMOUSE | SCSELKEY | SCDOUBLEQUIT);
23440 	for(i=0; i<us_tool->numvar; i++)
23441 	{
23442 		var = &us_tool->firstvar[i];
23443 		pt = makename(var->key);
23444 		if (namesamen(pt, x_("USER_windowview_"), 16) == 0) DiaStuffLine(dia, DWNV_VIEWLIST, &pt[16]);
23445 	}
23446 	DiaSelectLine(dia, DWNV_VIEWLIST, -1);
23447 
23448 	/* loop until done */
23449 	for(;;)
23450 	{
23451 		itemHit = DiaNextHit(dia);
23452 		if (itemHit == CANCEL) break;
23453 		if (itemHit == DWNV_RESTOREVIEW)
23454 		{
23455 			/* restore selected view */
23456 			par[0] = x_("name");
23457 			i = DiaGetCurLine(dia, DWNV_VIEWLIST);
23458 			if (i < 0) continue;
23459 			pt = DiaGetScrollLine(dia, DWNV_VIEWLIST, i);
23460 			(void)allocstring(&par[1], pt, el_tempcluster);
23461 			break;
23462 		}
23463 
23464 		if (itemHit == DWNV_SAVEVIEW)
23465 		{
23466 			/* save selected view */
23467 			if (!DiaValidEntry(dia, DWNV_VIEWNAME)) continue;
23468 			par[0] = x_("save");
23469 			par[1] = DiaGetText(dia, DWNV_VIEWNAME);
23470 			us_window(2, par);
23471 			DiaLoadTextDialog(dia, DWNV_VIEWLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
23472 			for(i=0; i<us_tool->numvar; i++)
23473 			{
23474 				var = &us_tool->firstvar[i];
23475 				pt = makename(var->key);
23476 				if (namesamen(pt, x_("USER_windowview_"), 16) == 0) DiaStuffLine(dia, DWNV_VIEWLIST, &pt[16]);
23477 			}
23478 			DiaSelectLine(dia, DWNV_VIEWLIST, -1);
23479 			continue;
23480 		}
23481 	}
23482 
23483 	DiaDoneDialog(dia);
23484 	if (itemHit == DWNV_RESTOREVIEW)
23485 	{
23486 		us_window(2, par);
23487 		efree(par[1]);
23488 	}
23489 	return(0);
23490 }
23491 
23492 /****************************** SUPPORT ******************************/
23493 
23494 /*
23495  * Routine to set the correct line selection in scroll item "scrollitem".  This item
23496  * has a list of cell names, and the current one should be selected.  If "curinstance"
23497  * is true, consider the currently selected cell instance (if any).  If "forcecurlib"
23498  * is true, strip off library names when matching.  If "justcells" is true, only
23499  * consider cell names, not cell names.
23500  */
us_setscrolltocurrentcell(INTBIG scrollitem,BOOLEAN curinstance,BOOLEAN curcell,BOOLEAN forcecurlib,BOOLEAN justcells,void * dia)23501 NODEPROTO *us_setscrolltocurrentcell(INTBIG scrollitem, BOOLEAN curinstance, BOOLEAN curcell,
23502 	BOOLEAN forcecurlib, BOOLEAN justcells, void *dia)
23503 {
23504 	Q_UNUSED( forcecurlib );
23505 	REGISTER NODEPROTO *np, *enp, *shownp;
23506 	REGISTER GEOM **list;
23507 	REGISTER CHAR *line, *curnode, *pt, *thisnode;
23508 	REGISTER NODEINST *ni;
23509 	REGISTER VARIABLE *var;
23510 	REGISTER INTBIG i, listlen;
23511 	REGISTER void *infstr;
23512 
23513 	/* find the current node */
23514 	np = getcurcell();
23515 	shownp = NONODEPROTO;
23516 
23517 	/* if we can use the current cell and it is valid, take it */
23518 	if (curcell && np != NONODEPROTO) shownp = np;
23519 
23520 	/* if there is an explorer window open, use it's selection */
23521 	enp = us_currentexplorernode();
23522 	if (enp != NONODEPROTO) shownp = enp;
23523 
23524 	curnode = 0;
23525 	if (shownp != NONODEPROTO)
23526 	{
23527 		if (justcells) curnode = shownp->protoname; else
23528 		{
23529 			curnode = nldescribenodeproto(shownp);
23530 		}
23531 	}
23532 
23533 	/* if there is a current cell, look at contents */
23534 	if (np != NONODEPROTO)
23535 	{
23536 		if (curinstance)
23537 		{
23538 			list = us_gethighlighted(WANTNODEINST, 0, 0);
23539 			if (list[0] != NOGEOM)
23540 			{
23541 				curnode = 0;
23542 				for(i=0; list[i] != NOGEOM; i++)
23543 				{
23544 					if (!list[i]->entryisnode)
23545 					{
23546 						curnode = 0;
23547 						break;
23548 					}
23549 					ni = list[i]->entryaddr.ni;
23550 					if (ni->proto->primindex != 0) continue;
23551 					if (justcells) thisnode = ni->proto->protoname; else
23552 						thisnode = nldescribenodeproto(ni->proto);
23553 					if (curnode == 0) curnode = thisnode; else
23554 					{
23555 						if (namesame(curnode, thisnode) != 0)
23556 						{
23557 							curnode = 0;
23558 							break;
23559 						}
23560 					}
23561 				}
23562 			}
23563 		}
23564 		if (namesame(np->protoname, x_("cellstructure")) == 0)
23565 		{
23566 			list = us_gethighlighted(WANTNODEINST, 0, 0);
23567 			if (list[0] != NOGEOM && list[1] == NOGEOM)
23568 			{
23569 				if (list[0]->entryisnode)
23570 				{
23571 					ni = list[0]->entryaddr.ni;
23572 					var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, art_messagekey);
23573 					if (var != NOVARIABLE)
23574 					{
23575 						curnode = (CHAR *)var->addr;
23576 						if (justcells)
23577 						{
23578 							infstr = initinfstr();
23579 							for(pt = curnode; *pt != 0; pt++)
23580 							{
23581 								if (*pt == ';' || *pt == '{') break;
23582 								addtoinfstr(infstr, *pt);
23583 							}
23584 							curnode = returninfstr(infstr);
23585 						}
23586 					}
23587 				}
23588 			}
23589 		}
23590 	}
23591 
23592 	/* now find it in the list */
23593 	if (curnode != 0)
23594 	{
23595 		listlen = DiaGetNumScrollLines(dia, scrollitem);
23596 		for(i=0; i<listlen; i++)
23597 		{
23598 			line = DiaGetScrollLine(dia, scrollitem, i);
23599 			if (estrcmp(line, curnode) == 0)
23600 			{
23601 				DiaSelectLine(dia, scrollitem, i);
23602 				break;
23603 			}
23604 		}
23605 	}
23606 	return(np);
23607 }
23608 
23609 /*
23610  * Routine to get face field of "textdescript" and set popup entry of "popupitem".
23611  * If "init" is TRUE "popupitem" is initialized by all system fonts.
23612  */
us_setpopupface(INTBIG popupitem,INTBIG face,BOOLEAN init,void * dia)23613 void us_setpopupface(INTBIG popupitem, INTBIG face, BOOLEAN init, void *dia)
23614 {
23615 	INTBIG i, facecount;
23616 	CHAR *facename, **facelist;
23617 
23618 	if (graphicshas(CANCHOOSEFACES))
23619 	{
23620 		if (init)
23621 		{
23622 			facecount = screengetfacelist(&facelist, TRUE);
23623 			DiaSetPopup(dia, popupitem, facecount, facelist);
23624 		}
23625 		facecount = screengetfacelist(&facelist, FALSE);
23626 		if (face >= facecount) face = 0;
23627 		i = 0;
23628 		if (face > 0)
23629 		{
23630 			facename = facelist[face];
23631 			facecount = screengetfacelist(&facelist, TRUE);
23632 			for (i = facecount - 1; i > 0 && namesame(facename, facelist[i]) != 0; i--);
23633 		}
23634 		DiaSetPopupEntry(dia, popupitem, i);
23635 	}
23636 }
23637 
23638 /*
23639  * Routine to set face field of "textdescript" to face selected by "popupitem".
23640  */
us_getpopupface(INTBIG popupitem,void * dia)23641 INTBIG us_getpopupface(INTBIG popupitem, void *dia)
23642 {
23643 	INTBIG value, facecount;
23644 	CHAR **facelist;
23645 
23646 	value = 0;
23647 	if (graphicshas(CANCHOOSEFACES))
23648 	{
23649 		value = DiaGetPopupEntry(dia, popupitem);
23650 		if (value > 0)
23651 		{
23652 			facecount = screengetfacelist(&facelist, TRUE);
23653 			value = screenfindface(facelist[value]);
23654 			if (value < 0)
23655 			{
23656 				ttyputerr(x_("Too many used fonts, using default"));
23657 				value = 0;
23658 				DiaSetPopupEntry(dia, popupitem, 0);
23659 			}
23660 		}
23661 	}
23662 	return(value);
23663 }
23664