1 /* "NETGEN", a netlist-specification tool for VLSI
2    Copyright (C) 1989, 1990   Massimo A. Sivilotti
3    Author's address: mass@csvax.cs.caltech.edu;
4                      Caltech 256-80, Pasadena CA 91125.
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation (any version).
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file copying.  If not, write to
17 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 
19 
20 /* xnetgen.c: X11 interface to netgen */
21 
22 /*
23  * define ONE of the following:
24  *
25  *   X11_HP_WIDGETS
26  *   X11_MOTIF_WIDGETS
27  *   X11_ATHENA_WIDGETS
28  */
29 
30 
31 #ifdef HAVE_X11
32 
33 #include "config.h"
34 #include <stdio.h>
35 
36 /* #define volatile */  /* hacks for /usr/include/sys/types.h */
37 /* #define signed */
38 
39 /* #define XLIB_ILLEGAL_ACCESS */ /* hack for SGI---not supposed to use Display->db */
40 
41 #include <X11/Xlib.h>
42 #include <X11/Intrinsic.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Xutil.h>
45 #include <X11/Shell.h>
46 
47 #ifdef HPUX
48 #undef SIGCHLD
49 #endif
50 
51 #include <setjmp.h>
52 #include <signal.h>
53 
54 #include "netgen.h"
55 #include "timing.h"
56 #include "query.h"
57 #include "xnetgen.h"
58 #include "netcmp.h"
59 #include "objlist.h"
60 #include "print.h"
61 #include "dbug.h"
62 
63 
64 
65 
66 Widget toplevel = NULL;
67 
68 char GlobalFileName[100],
69   GlobalCellName[100],
70   GlobalOtherName[100],
71   GlobalDataName[100];
72 
73 /*********************************************************
74  * Menu structure:  attaches label string to a function,
75  * and optionally points to a sub-menu.
76  *********************************************************/
77 
78 typedef struct menu_menu {
79   char *name;
80   void (*func)();
81   struct menu_menu *submenu;
82   caddr_t data;
83 } menu_struct;
84 
85 
86 /**********************************************************************
87          USER - SUPPLIED ACTION COMMANDS
88 **********************************************************************/
89 
90 Widget GlobalFileWidget;
91 Widget GlobalCellWidget;
92 Widget GlobalOtherWidget;
93 Widget GlobalDataWidget;
94 
95 char *get_file(void);
96 char *get_cell(void);
97 char *get_other(void);
98 char *get_data(void);
99 
100 static int timing = 0;
101 static float StartTime;
102 
X_END(void)103 void X_END(void)
104 {
105   if (timing) Printf("Execution time: %0.2f\n", ElapsedCPUTime(StartTime));
106   Printf("\n");
107   X_display_refresh();
108 }
109 
X_START(void)110 void X_START(void)
111 {
112   *GlobalFileName = '\0';
113   *GlobalCellName = '\0';
114   *GlobalOtherName = '\0';
115   *GlobalDataName = '\0';
116   if (timing) StartTime = CPUTime();
117 }
118 
no_command(Widget w,Widget textwidget,caddr_t call_data)119 void no_command(Widget w, Widget textwidget, caddr_t call_data)
120 {
121   XBell(XtDisplay(w), 100);
122   Printf("No such command!\n");
123   X_END();
124 }
125 
not_yet_implemented(Widget w,Widget textwidget,caddr_t call_data)126 void not_yet_implemented(Widget w, Widget textwidget, caddr_t call_data)
127 {
128   XBell(XtDisplay(w), 100);
129   Printf("Command not yet implemented!\n");
130   X_END();
131 }
132 
133 /*******************  OUTPUT FILE FORMATS *****************************/
134 
write_ntk(Widget w,Widget textwidget,caddr_t call_data)135 void write_ntk(Widget w, Widget textwidget, caddr_t call_data)
136 {
137   X_START();
138   Ntk(get_cell(), NULL);
139   X_END();
140 }
141 
write_actel(Widget w,Widget textwidget,caddr_t call_data)142 void write_actel(Widget w, Widget textwidget, caddr_t call_data)
143 {
144   X_START();
145   Actel(get_cell(), NULL);
146   X_END();
147 }
148 
write_wombat(Widget w,Widget textwidget,caddr_t call_data)149 void write_wombat(Widget w, Widget textwidget, caddr_t call_data)
150 {
151   X_START();
152   Wombat(get_cell(), NULL);
153   X_END();
154 }
155 
write_ext(Widget w,Widget textwidget,caddr_t call_data)156 void write_ext(Widget w, Widget textwidget, caddr_t call_data)
157 {
158   X_START();
159   Ext(get_cell());
160   X_END();
161 }
162 
write_sim(Widget w,Widget textwidget,caddr_t call_data)163 void write_sim(Widget w, Widget textwidget, caddr_t call_data)
164 {
165   X_START();
166   Sim(get_cell());
167   X_END();
168 }
169 
write_spice(Widget w,Widget textwidget,caddr_t call_data)170 void write_spice(Widget w, Widget textwidget, caddr_t call_data)
171 {
172   X_START();
173   SpiceCell(get_cell(), -1, NULL);
174   X_END();
175 }
176 
write_esacap(Widget w,Widget textwidget,caddr_t call_data)177 void write_esacap(Widget w, Widget textwidget, caddr_t call_data)
178 {
179   X_START();
180   EsacapCell(get_cell(), NULL);
181   X_END();
182 }
183 
write_ccode(Widget w,Widget textwidget,caddr_t call_data)184 void write_ccode(Widget w, Widget textwidget, caddr_t call_data)
185 {
186   X_START();
187   Ccode(get_cell(), NULL);
188   X_END();
189 }
190 
write_netgen(Widget w,Widget textwidget,caddr_t call_data)191 void write_netgen(Widget w, Widget textwidget, caddr_t call_data)
192 {
193   X_START();
194   WriteNetgenFile(get_cell(), NULL);
195   X_END();
196 }
197 
198 static menu_struct WriteMenu[] = {
199   { "NTK", write_ntk, NULL, NULL },
200   { "Actel", write_actel, NULL, NULL },
201   { "Wombat", write_wombat, NULL, NULL },
202   { "Spice", write_spice, NULL, NULL },
203   { "Esacap", write_esacap, NULL, NULL },
204   { "Netgen", write_netgen, NULL, NULL },
205   { "Ext",  write_ext, NULL, NULL },
206   { "Sim",  write_sim, NULL, NULL },
207   { "C code", write_ccode, NULL, NULL },
208   { NULL }
209 };
210 
211 
212 /*******************  INPUT FILE FORMATS *****************************/
213 
read_ntk(Widget w,Widget textwidget,caddr_t call_data)214 void read_ntk(Widget w, Widget textwidget, caddr_t call_data)
215 {
216   X_START();
217   ReadNtk(get_file());
218   X_END();
219 }
220 
read_actel(Widget w,Widget textwidget,caddr_t call_data)221 void read_actel(Widget w, Widget textwidget, caddr_t call_data)
222 {
223   X_START();
224   Printf("Reading ACTEL library.\n");
225   X_END();
226 }
227 
read_ext(Widget w,Widget textwidget,caddr_t call_data)228 void read_ext(Widget w, Widget textwidget, caddr_t call_data)
229 {
230   X_START();
231   ReadExtHier(get_file());
232   X_END();
233 }
234 
read_sim(Widget w,Widget textwidget,caddr_t call_data)235 void read_sim(Widget w, Widget textwidget, caddr_t call_data)
236 {
237   X_START();
238   ReadSim(get_file());
239   X_END();
240 }
241 
read_spice(Widget w,Widget textwidget,caddr_t call_data)242 void read_spice(Widget w, Widget textwidget, caddr_t call_data)
243 {
244   X_START();
245   ReadSpice(get_file());
246   X_END();
247 }
248 
read_netgen(Widget w,Widget textwidget,caddr_t call_data)249 void read_netgen(Widget w, Widget textwidget, caddr_t call_data)
250 {
251   X_START();
252   ReadNetgenFile(get_file());
253   X_END();
254 }
255 
256 static menu_struct ReadMenu[] = {
257   { "NTK", read_ntk, NULL, NULL },
258   { "Actel Library", read_actel, NULL, NULL },
259   { "Spice", read_spice, NULL, NULL },
260   { "Ext",  read_ext, NULL, NULL },
261   { "Sim",  read_sim, NULL, NULL },
262   { "Netgen", read_netgen, NULL, NULL },
263   { NULL }
264 };
265 
266 
267 /**************************** NETCMP MENU ****************************/
268 
initialize_netcmp_datastructures(Widget w,Widget textwidget,caddr_t call_data)269 void initialize_netcmp_datastructures(Widget w, Widget textwidget,
270 				      caddr_t call_data)
271 {
272   X_START();
273   Printf("Comparing cells '%s' and '%s'\n", get_cell(), get_other());
274   CreateTwoLists(get_cell(), get_other(), 0);
275   Permute();
276 #ifdef DEBUG_ALLOC
277   PrintCoreStats();
278 #endif
279   X_END();
280 }
281 
iterate_netcmp(Widget w,Widget textwidget,caddr_t call_data)282 void iterate_netcmp(Widget w, Widget textwidget, caddr_t call_data)
283 {
284   X_START();
285   if (!Iterate()) Printf("Please iterate again\n");
286   else Printf("No fractures made: NETCMP has converged\n");
287   X_END();
288 }
289 
print_netcmp_automorphisms(Widget w,Widget textwidget,caddr_t call_data)290 void print_netcmp_automorphisms(Widget w, Widget textwidget, caddr_t call_data)
291 {
292   X_START();
293   PrintAutomorphisms();
294   X_END();
295 }
296 
resolve_automorphisms(Widget w,Widget textwidget,caddr_t call_data)297 void resolve_automorphisms(Widget w, Widget textwidget, caddr_t call_data)
298 {
299   int automorphisms;
300 
301   X_START();
302   while ((automorphisms = ResolveAutomorphisms()) > 0) ;
303   if (automorphisms == -1) Printf("Graphs do not match.\n");
304   else Printf("Circuits match correctly.\n");
305   X_END();
306 }
307 
converge_netcmp(Widget w,Widget textwidget,caddr_t call_data)308 void converge_netcmp(Widget w, Widget textwidget, caddr_t call_data)
309 {
310   int automorphisms;
311 #if 1
312   X_START();
313   while (!Iterate()) ;
314   automorphisms = VerifyMatching();
315   if (automorphisms == -1) Printf("Graphs do not match.\n");
316   else {
317     if (automorphisms)
318       Printf("Circuits match with %d automorphisms\n", automorphisms);
319     else Printf("Circuits match correctly.\n");
320   }
321   X_END();
322 #else
323   while (!Iterate()) ;
324   /* go check automorphisms */
325   print_netcmp_automorphisms(w, textwidget, call_data);
326 #endif
327 }
328 
print_netcmp_classes(Widget w,Widget textwidget,caddr_t call_data)329 void print_netcmp_classes(Widget w, Widget textwidget, caddr_t call_data)
330 {
331   X_START();
332   PrintElementClasses(ElementClasses, -1, 0);
333   PrintNodeClasses(NodeClasses, -1, 0);
334   X_END();
335 }
336 
verify_netcmp(Widget w,Widget textwidget,caddr_t call_data)337 void verify_netcmp(Widget w, Widget textwidget, caddr_t call_data)
338 {
339   X_START();
340   if (ElementClasses == NULL || NodeClasses == NULL)
341     Printf("Must initialize data structures first\n");
342   else {
343     int automorphisms;
344     automorphisms = VerifyMatching();
345     if (automorphisms == -1) Printf("Graphs do not match.\n");
346     else {
347       if (automorphisms)
348 	Printf("Circuits match with %d automorphisms\n", automorphisms);
349       else Printf("Circuits match correctly.\n");
350     }
351   }
352   X_END();
353 }
354 
equivalence_netcmp_elements(Widget w,Widget textwidget,caddr_t call_data)355 void equivalence_netcmp_elements(Widget w, Widget textwidget, caddr_t call_data)
356 {
357   X_START();
358   Printf("Equivalence elements '%s' and '%s'\n", get_data(), get_other());
359   if (EquivalenceElements(get_data(), -1, get_other(), -1))
360     Printf("Done.\n");
361   else Printf("Unable to equivalence elements %s and %s\n",
362 	      get_data(), get_other());
363   X_END();
364 }
365 
equivalence_netcmp_nodes(Widget w,Widget textwidget,caddr_t call_data)366 void equivalence_netcmp_nodes(Widget w, Widget textwidget, caddr_t call_data)
367 {
368   X_START();
369   Printf("Equivalence nodes '%s' and '%s'\n", get_data(), get_other());
370   if (EquivalenceNodes(get_data(), -1, get_other(), -1))
371     Printf("Done.\n");
372   else Printf("Unable to equivalence nodes %s and %s\n",
373 	      get_data(), get_other());
374   X_END();
375 }
376 
permute_netcmp_pins(Widget w,Widget textwidget,caddr_t call_data)377 void permute_netcmp_pins(Widget w, Widget textwidget, caddr_t call_data)
378 {
379   X_START();
380   Printf("Cell '%s': permuting pins '%s' and '%s'\n",
381 	 get_cell(), get_data(), get_other());
382   if (PermuteSetup(get_cell(), -1, get_data(), get_other()))
383     Printf("%s == %s\n",get_data(), get_other());
384   else Printf("Unable to permute pins %s, %s\n",get_data(), get_other());
385   X_END();
386 }
387 
permute_netcmp_transistors(Widget w,Widget textwidget,caddr_t call_data)388 void permute_netcmp_transistors(Widget w, Widget textwidget, caddr_t call_data)
389 {
390   X_START();
391   if (PermuteSetup("n", -1, "drain", "source"))
392     Printf("n-channel: source == drain\n");
393   if (PermuteSetup("p", -1, "drain", "source"))
394     Printf("p-channel: source == drain\n");
395   if (PermuteSetup("e", -1, "bottom_a", "bottom_b"))
396     Printf("poly cap: permuting poly1 regions\n");
397   if (PermuteSetup("r", -1, "end_a", "end_b"))
398     Printf("resistor: permuting endpoints\n");
399   if (PermuteSetup("c", -1, "bot", "top"))
400     Printf("capacitor: permuting sides\n");
401   X_END();
402 }
403 
exhaustive_netcmp_subdivision(Widget w,Widget textwidget,caddr_t call_data)404 void exhaustive_netcmp_subdivision(Widget w, Widget textwidget,
405 				   caddr_t call_data)
406 {
407   X_START();
408   ExhaustiveSubdivision = !ExhaustiveSubdivision;
409   Printf("Exhaustive subdivision %s\n",
410 	 ExhaustiveSubdivision ? "ENABLED" : "DISABLED");
411   X_END();
412 }
413 
restart_netcmp(Widget w,Widget textwidget,caddr_t call_data)414 void restart_netcmp(Widget w, Widget textwidget, caddr_t call_data)
415 {
416   X_START();
417   Printf("Resetting NETCMP data structures\n");
418   RegroupDataStructures();
419   X_END();
420 }
421 
summarize_netcmp_data(Widget w,Widget textwidget,caddr_t call_data)422 void summarize_netcmp_data(Widget w, Widget textwidget, caddr_t call_data)
423 {
424   X_START();
425   SummarizeElementClasses(ElementClasses);
426   SummarizeNodeClasses(NodeClasses);
427   X_END();
428 }
429 
sleep_ten_seconds(Widget w,Widget textwidget,caddr_t call_data)430 void sleep_ten_seconds(Widget w, Widget textwidget, caddr_t call_data)
431 {
432   X_START();
433   sleep(10);
434   X_END();
435 }
436 
437 static menu_struct NetcmpMenu[] = {
438   { "Initialize", initialize_netcmp_datastructures, NULL, NULL },
439   { "Iterate", iterate_netcmp, NULL, NULL },
440   { "Converge", converge_netcmp, NULL, NULL },
441   { "Print classes", print_netcmp_classes, NULL, NULL },
442   { "Verify results", verify_netcmp, NULL, NULL },
443   { "Print automorphisms", print_netcmp_automorphisms, NULL, NULL },
444   { "Resolve automorphisms", resolve_automorphisms, NULL, NULL },
445   { "Equivalence elements", equivalence_netcmp_elements, NULL, NULL },
446   { "Equivalence nodes", equivalence_netcmp_nodes, NULL, NULL },
447   { "Permute pins", permute_netcmp_pins, NULL, NULL },
448   { "Permute source/drains", permute_netcmp_transistors, NULL, NULL },
449   { "Exhaustive subdivision", exhaustive_netcmp_subdivision, NULL, NULL },
450   { "Restart algorithm", restart_netcmp, NULL, NULL },
451   { "Summarize datastructures", summarize_netcmp_data, NULL, NULL },
452   { "SLEEP", sleep_ten_seconds, NULL, NULL},
453   { NULL }
454 };
455 
456 /**************************** PROTO MENU ****************************/
457 
458 
459 /* embedding sub-menu */
460 
proto_embed_greedy(Widget w,Widget textwidget,caddr_t call_data)461 void proto_embed_greedy(Widget w, Widget textwidget, caddr_t call_data)
462 {
463   X_START();
464   ProtoEmbed(get_cell(), 'g');
465   X_END();
466 }
467 
proto_embed_anneal(Widget w,Widget textwidget,caddr_t call_data)468 void proto_embed_anneal(Widget w, Widget textwidget, caddr_t call_data)
469 {
470   X_START();
471   ProtoEmbed(get_cell(), 'a');
472   X_END();
473 }
474 
proto_embed_random(Widget w,Widget textwidget,caddr_t call_data)475 void proto_embed_random(Widget w, Widget textwidget, caddr_t call_data)
476 {
477   X_START();
478   ProtoEmbed(get_cell(), 'r');
479   X_END();
480 }
481 
proto_embed_bottup(Widget w,Widget textwidget,caddr_t call_data)482 void proto_embed_bottup(Widget w, Widget textwidget, caddr_t call_data)
483 {
484   X_START();
485   ProtoEmbed(get_cell(), 'o');
486   X_END();
487 }
488 
489 
490 static menu_struct ProtoEmbedMenu[] = {
491   { "Greedy", proto_embed_greedy, NULL, NULL },
492   { "Anneal", proto_embed_anneal, NULL, NULL },
493   { "Random", proto_embed_random, NULL, NULL },
494   { "BottomUp", proto_embed_bottup, NULL, NULL },
495   { NULL }
496 };
497 
498 
499 /* show-parameters sub-menu */
500 
proto_print_parameters(Widget w,Widget textwidget,caddr_t call_data)501 void proto_print_parameters(Widget w, Widget textwidget, caddr_t call_data)
502 {
503   X_START();
504   ProtoPrintParameters();
505   X_END();
506 }
507 
proto_leaf_pinout(Widget w,Widget textwidget,caddr_t call_data)508 void proto_leaf_pinout(Widget w, Widget textwidget, caddr_t call_data)
509 {
510   X_START();
511   SetupLeafPinout(get_other());
512   X_END();
513 }
514 
proto_rent_exp(Widget w,Widget textwidget,caddr_t call_data)515 void proto_rent_exp(Widget w, Widget textwidget, caddr_t call_data)
516 {
517   X_START();
518   SetupRentExp(get_other());
519   X_END();
520 }
521 
proto_tree_fanout(Widget w,Widget textwidget,caddr_t call_data)522 void proto_tree_fanout(Widget w, Widget textwidget, caddr_t call_data)
523 {
524   X_START();
525   SetupTreeFanout(get_other());
526   X_END();
527 }
528 
proto_min_common_nodes(Widget w,Widget textwidget,caddr_t call_data)529 void proto_min_common_nodes(Widget w, Widget textwidget, caddr_t call_data)
530 {
531   X_START();
532   SetupMinCommonNodes(get_other());
533   X_END();
534 }
535 
proto_min_used_leaves(Widget w,Widget textwidget,caddr_t call_data)536 void proto_min_used_leaves(Widget w, Widget textwidget, caddr_t call_data)
537 {
538   X_START();
539   SetupMinUsedLeaves(get_other());
540   X_END();
541 }
542 
543 static menu_struct ProtoConstMenu[] = {
544   { "Show parameters", proto_print_parameters, NULL, NULL },
545   { "Leaf pinout", proto_leaf_pinout, NULL, NULL },
546   { "Rent's rule exp", proto_rent_exp, NULL, NULL },
547   { "Tree fanout", proto_tree_fanout, NULL, NULL },
548   { "Common node reqs", proto_min_common_nodes, NULL, NULL },
549   { "Leaf containment", proto_min_used_leaves, NULL, NULL },
550   { NULL }
551 };
552 
553 
proto_toggle_logging(Widget w,Widget textwidget,caddr_t call_data)554 void proto_toggle_logging(Widget w, Widget textwidget, caddr_t call_data)
555 {
556   X_START();
557   ToggleLogging();
558   X_END();
559 }
560 
proto_toggle_exhaustive(Widget w,Widget textwidget,caddr_t call_data)561 void proto_toggle_exhaustive(Widget w, Widget textwidget, caddr_t call_data)
562 {
563   X_START();
564   ToggleExhaustive();
565   X_END();
566 }
567 
proto_toggle_debug(Widget w,Widget textwidget,caddr_t call_data)568 void proto_toggle_debug(Widget w, Widget textwidget, caddr_t call_data)
569 {
570   X_START();
571   ToggleDebug();
572   X_END();
573 }
574 
proto_describe_cell(Widget w,Widget textwidget,caddr_t call_data)575 void proto_describe_cell(Widget w, Widget textwidget, caddr_t call_data)
576 {
577   X_START();
578   DescribeCell(get_cell(), 0);
579   X_END();
580 }
581 
582 
583 
584 static menu_struct ProtoMenu[] = {
585   { "PROTOCHIP parameters", no_command, ProtoConstMenu, NULL },
586   { "Embed cell", no_command, ProtoEmbedMenu, NULL },
587   { "Toggle logging", proto_toggle_logging, NULL, NULL },
588   { "Toggle exhaustive", proto_toggle_exhaustive, NULL, NULL },
589   { "Toggle debug", proto_toggle_debug, NULL, NULL },
590   { "Describe cell", proto_describe_cell, NULL, NULL },
591   { NULL }
592 };
593 
594 
595 
596 /****************************  PRINT MENU ******************************/
597 
598 
print_cell(Widget w,Widget textwidget,caddr_t call_data)599 void print_cell(Widget w, Widget textwidget, caddr_t call_data)
600 {
601   X_START();
602   Printf("Contents of cell: %s\n", get_cell());
603   PrintCell(get_cell());
604   X_END();
605 }
606 
print_instances(Widget w,Widget textwidget,caddr_t call_data)607 void print_instances(Widget w, Widget textwidget, caddr_t call_data)
608 {
609   X_START();
610   Printf("Instances within cell: %s\n", get_cell());
611   PrintInstances(get_cell());
612   X_END();
613 }
614 
describe_instance(Widget w,Widget textwidget,caddr_t call_data)615 void describe_instance(Widget w, Widget textwidget, caddr_t call_data)
616 {
617   X_START();
618   Printf("Describe instance: %s\n", get_cell());
619   DescribeInstance(get_cell(), -1);
620   X_END();
621 }
622 
print_nodes(Widget w,Widget textwidget,caddr_t call_data)623 void print_nodes(Widget w, Widget textwidget, caddr_t call_data)
624 {
625   X_START();
626   Printf("Nodes in cell: %s\n", get_cell());
627   PrintNodes(get_cell(), -1);
628   X_END();
629 }
630 
print_nodes_connected_to(Widget w,Widget textwidget,caddr_t call_data)631 void print_nodes_connected_to(Widget w, Widget textwidget, caddr_t call_data)
632 {
633   X_START();
634   Fanout(get_cell(), get_data(), NODE);
635   X_END();
636 }
637 
print_element(Widget w,Widget textwidget,caddr_t call_data)638 void print_element(Widget w, Widget textwidget, caddr_t call_data)
639 {
640   X_START();
641   Printf("In cell %s\n",  get_cell());
642   PrintElement(get_cell(), get_data());
643   X_END();
644 }
645 
print_ports(Widget w,Widget textwidget,caddr_t call_data)646 void print_ports(Widget w, Widget textwidget, caddr_t call_data)
647 {
648   X_START();
649   Printf("Ports in cell: %s\n",  get_cell());
650   PrintPortsInCell(get_cell(), -1);
651   X_END();
652 }
653 
print_leaves(Widget w,Widget textwidget,caddr_t call_data)654 void print_leaves(Widget w, Widget textwidget, caddr_t call_data)
655 {
656   X_START();
657   Printf("Leaves in cell: %s\n",  get_cell());
658   PrintLeavesInCell(get_cell(), -1);
659   X_END();
660 }
661 
662 
663 static menu_struct PrintMenu[] = {
664   { "Print cell", print_cell, NULL, NULL},
665   { "Print nodes", print_nodes, NULL, NULL},
666   { "Print fanout", print_nodes_connected_to, NULL, NULL},
667   { "Print element", print_element, NULL, NULL},
668   { "Print instances", print_instances, NULL, NULL},
669   { "Describe instance", describe_instance, NULL, NULL},
670   { "Print ports", print_ports, NULL, NULL},
671   { "Print leaves", print_leaves, NULL, NULL},
672   { NULL }
673 };
674 
675 
676 /****************************  MAIN MENU *******************************/
677 
list_cells(Widget w,Widget textwidget,caddr_t call_data)678 void list_cells(Widget w, Widget textwidget, caddr_t call_data)
679 {
680   X_START();
681   PrintCellHashTable(1, -1);
682   X_END();
683 }
684 
read_cell(Widget w,Widget textwidget,caddr_t call_data)685 void read_cell(Widget w, Widget textwidget, caddr_t call_data)
686 {
687   X_START();
688   Printf("Read file: %s\n", get_file());
689   ReadNetlist(get_file());
690   X_END();
691 }
692 
flatten_cell(Widget w,Widget textwidget,caddr_t call_data)693 void flatten_cell(Widget w, Widget textwidget, caddr_t call_data)
694 {
695   X_START();
696   Printf("Flatten cell: %s\n", get_cell());
697   Flatten(get_cell(), -1);
698   X_END();
699 }
700 
flatten_instances_of(Widget w,Widget textwidget,caddr_t call_data)701 void flatten_instances_of(Widget w, Widget textwidget, caddr_t call_data)
702 {
703   X_START();
704   Printf("Flatten instances of: %s\n", get_cell());
705   FlattenInstancesOf(get_cell());
706   X_END();
707 }
708 
709 
print_all_leaves(Widget w,Widget textwidget,caddr_t call_data)710 void print_all_leaves(Widget w, Widget textwidget, caddr_t call_data)
711 {
712   X_START();
713   Printf("Leaves\n");
714   PrintAllLeaves();
715   X_END();
716 }
717 
dbug_command(Widget w,Widget textwidget,caddr_t call_data)718 void dbug_command(Widget w, Widget textwidget, caddr_t call_data)
719 {
720   X_START();
721   Printf("DBUG command: %s\n", get_data());
722   DBUG_PUSH(get_data());
723   X_END();
724 }
725 
read_command_file(Widget w,Widget textwidget,caddr_t call_data)726 void read_command_file(Widget w, Widget textwidget, caddr_t call_data)
727 {
728   FILE *oldfile;
729 
730   X_START();
731   Printf("Reading command file: %s\n", get_file());
732   oldfile = promptstring_infile;
733   promptstring_infile = fopen(get_file(), "r");
734   if (promptstring_infile == NULL)
735     Printf("Unable to open command file: %s\n", get_file());
736   else {
737     Query();
738     fclose(promptstring_infile);
739     Printf("Finished executing command file: %s\n", get_file());
740   }
741   promptstring_infile = oldfile;
742   X_END();
743 }
744 
dump_screen_to_file(Widget w,Widget textwidget,caddr_t call_data)745 void dump_screen_to_file(Widget w, Widget textwidget, caddr_t call_data)
746 /* toggle dumping log file based on status of LoggingFile */
747 {
748   Arg Args[10];
749   int n;
750 
751   X_START();
752   n = 0;
753   XtSetArg(Args[n], XtNstring, "TOGGLE LOG"); n++;
754   XtSetValues(w, Args, n);
755 
756   if (LoggingFile == NULL) {
757     /* install logging file */
758     FILE *file;
759     file = fopen(get_file(), "r");
760     if (file != NULL && strlen(get_file()) != 0) {
761       Printf("File %s exists already.  Output written to 'netgen.log'.\n",
762 	     get_file());
763       fclose(file);
764       file = fopen("netgen.log", "w");
765     }
766     else file = fopen(get_file(), "w");
767     if (file == NULL) Printf("Unable to open file.\n");
768     else {
769       Printf("Logging enabled.\n");
770       LoggingFile = file;
771     }
772 #if 0
773     /* dump the contents of the main window, line by line */
774     int i;
775     for (i = 0; i < data.nitems; i++) {
776       fputs(data.chars[i], file);
777       fputs("\n", file);
778     }
779 #endif
780   }
781   else {
782     /* log file is open, so close it */
783     fclose(LoggingFile);
784     LoggingFile = NULL;
785     Printf("Logging file closed.\n");
786   }
787   X_END();
788 }
789 
790 
toggle_timing(Widget w,Widget textwidget,caddr_t call_data)791 void toggle_timing(Widget w, Widget textwidget, caddr_t call_data)
792 {
793   if (timing) {
794     Printf("Timing disabled.\n");
795     timing = 0;
796     X_END;
797   }
798   else {
799     Printf("Timing of commands enabled.\n");
800     StartTime = CPUTime();
801     X_END();
802     timing = 1;
803   }
804 }
805 
806 
quit(Widget w,Widget textwidget,caddr_t call_data)807 void quit(Widget w, Widget textwidget, caddr_t call_data)
808 {
809   if (LoggingFile != NULL) fclose(LoggingFile);
810   XtDestroyWidget(toplevel);
811   exit(0);
812 }
813 
814 
815 static menu_struct Menu[] = {
816   { "List cells", list_cells, NULL, NULL},
817   { "Print", no_command, PrintMenu, NULL},
818   { "Flatten cell", flatten_cell, NULL, NULL},
819   { "Flatten instances of", flatten_instances_of, NULL, NULL},
820   { "List all leaves", print_all_leaves, NULL, NULL},
821   { "Read cell", read_cell, ReadMenu, NULL },
822   { "Write cell", no_command, WriteMenu, NULL },
823 /*
824   how to create a popup menu
825   { "popup",  pop_it_up, NULL, NULL},
826 */
827   { "NETCMP", no_command, NetcmpMenu, NULL},
828   { "PROTOCHIP", no_command, ProtoMenu, NULL},
829   { "DBUG command",   dbug_command, NULL, NULL},
830   { "Read command file", read_command_file, NULL, NULL},
831   { "Toggle log file", dump_screen_to_file, NULL, NULL},
832   { "Toggle timing", toggle_timing, NULL, NULL},
833   { "Quit",   quit, NULL, NULL},
834   { NULL }
835 };
836 
837 #if 0
838 #define ItemsInMenu(a) (sizeof (a) / sizeof(a[0]))
839 #else
ItemsInMenu(menu_struct * menulist)840 int ItemsInMenu(menu_struct *menulist)
841 {
842   menu_struct *p;
843   int i;
844 
845   i = 0;
846   for (p = menulist; p->name != NULL; p++) i++;
847   return(i);
848 }
849 #endif
850 
851 
852 #if defined(X11_MOTIF_WIDGETS) || defined(X11_ATHENA_WIDGETS)
853 
854 /* menu stuff:  emulate menus with persistent list widgets */
855 
856 struct menu_list {
857   Widget widget;
858   menu_struct *menu;
859 };
860 
861 /* the first component is the List widget that emulates the menu */
862 struct menu_list MenuArray[] = {
863   {NULL, Menu},
864   {NULL, WriteMenu},
865   {NULL, ReadMenu},
866   {NULL, PrintMenu},
867   {NULL, NetcmpMenu},
868   {NULL, ProtoEmbedMenu},
869   {NULL, ProtoConstMenu},
870   {NULL, ProtoMenu},
871 };
872 #endif /* MOTIF or ATHENA */
873 
874 
875 
876 #ifdef X11_HP_WIDGETS
877 
878 /**********************************************************************/
879 /*             HP-Widget-specific code follows:                       */
880 /**********************************************************************/
881 
882 
883 #undef INTERNAL_ARGS
884 #define CELL_LIST_MENU
885 
886 #undef INCLUDE_FALLBACK /* requires R4 Toolkit */
887 
888 #include <X11/Xw/Xw.h>
889 #include <X11/Xw/Form.h>
890 #include <X11/Xw/WorkSpace.h>
891 #include <X11/Xw/ScrollBar.h>
892 
893 #include <X11/Xw/RCManager.h>
894 #include <X11/Xw/BBoard.h>
895 #include <X11/Xw/VPW.h>
896 
897 /* these are for the menus */
898 #include <X11/Shell.h>
899 #include <X11/Xw/MenuBtn.h>
900 #include <X11/Xw/Cascade.h>
901 #include <X11/Xw/PopupMgr.h>
902 
903 /* for the one-line editor */
904 #include <X11/Xw/TextEdit.h>
905 #include <X11/Xw/SText.h>
906 
907 #include <X11/Xw/PButton.h>
908 #include <X11/Xw/TitleBar.h>
909 
910 #include <X11/Xw/Valuator.h>
911 #include <X11/Xw/Arrow.h>
912 #include <X11/Xw/SWindow.h>
913 
914 
915 #define MAXLINESIZE 300
916 #define MAXLINES 200
917 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
918 #define MARGIN 5
919 
920 typedef struct {
921   char *chars[MAXLINES];   /* Lines of text               */
922   int ll[MAXLINES];        /* Length of each line         */
923   int rbearing[MAXLINES];  /* right bearing of each line  */
924   int descent;		   /* descent below baseline	  */
925   int foreground,	   /* Color used for text	  */
926       background;
927   XFontStruct *font;	   /* The font struct		  */
928   GC gc;		   /* A read/write GC		  */
929   GC gcread;		   /* A read-only GC		  */
930   Widget scrollbar;
931   Widget canvas;
932   Dimension canvas_height; /* canvas dimensions		  */
933   Dimension canvas_width;
934   int fontheight;	   /* descent + ascent            */
935   int nitems;		   /* number of text lines	  */
936   int top;		   /* line at top of window	  */
937 } text_data, *text_data_ptr;
938 
939 text_data data;
940 text_data cells;
941 
942 
943 static XtResource resources[] = {
944   { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
945       XtOffset(text_data_ptr, font), XtRString, "Fixed"      },
946   { XtNforeground, XtCForeground, XtRPixel, sizeof(int),
947       XtOffset(text_data_ptr, foreground), XtRString, "Black"},
948   { XtNbackground, XtCBackground, XtRPixel, sizeof(int),
949       XtOffset(text_data_ptr, background), XtRString, "White"}
950 };
951 
952 String fallback_resources[] = {
953     "*yResizeable:                  True",
954     "*yAttachBottom:                True",
955     NULL,
956   };
957 
get_file(void)958 char *get_file(void)
959 {
960   return (XwTextCopyBuffer(GlobalFileWidget));
961 }
962 
get_cell(void)963 char *get_cell(void)
964 {
965   return (XwTextCopyBuffer(GlobalCellWidget));
966 }
967 
get_other(void)968 char *get_other(void)
969 {
970   return (XwTextCopyBuffer(GlobalOtherWidget));
971 }
972 
get_data(void)973 char *get_data(void)
974 {
975   return (XwTextCopyBuffer(GlobalDataWidget));
976 }
977 
978 
add_line(text_data * data,char * buf)979 add_line(text_data *data, char *buf)
980 {
981   /* this should be followed by a "refresh" as soon as possible */
982   int foreground, background, dir, ascent, desc;
983   XCharStruct char_info;
984   int i;
985 
986 #define JUMPSIZE 40
987   if (data->nitems >= MAXLINES) {
988     /* need to shuffle everything forward */
989     for (i = 0; i < JUMPSIZE; i++) XtFree(data->chars[i]);
990 
991     for (i = JUMPSIZE; i < MAXLINES; i++) {
992       data->chars[i-JUMPSIZE] = data->chars[i];
993       data->ll[i - JUMPSIZE] = data->ll[i];
994       data->rbearing[i - JUMPSIZE] = data->rbearing[i];
995     }
996     data->nitems -= JUMPSIZE;
997     data->top -= JUMPSIZE;
998   }
999 
1000   i = data->nitems;
1001   data->chars[i] = XtMalloc(strlen(buf) + 1);
1002   strcpy(data->chars[i], buf);
1003   data->ll[i] = strlen(data->chars[i]);
1004   XTextExtents(data->font, data->chars[i], data->ll[i], &dir, &ascent,
1005 	       &desc, &char_info);
1006   data->rbearing[i] = char_info.rbearing;
1007   data->descent = desc;
1008   data->fontheight = ascent + desc;
1009   while ((data->nitems - data->top) * data->fontheight > data->canvas_height)
1010     (data->top)++;
1011 
1012   (data->nitems)++;
1013 }
1014 
1015 
X_display_line(char * buf)1016 void X_display_line(char *buf)
1017 {
1018   char *pt, *tmpbuf, *startpt;
1019 
1020   if (toplevel == NULL) {
1021     /* not using X windows */
1022     printf("%s", buf);
1023     return;
1024   }
1025   tmpbuf = XtMalloc(strlen(buf) + 1);
1026   strcpy(tmpbuf, buf);
1027 #if 1
1028   /* eat last char if it is a '\n' */
1029   pt = strrchr(tmpbuf, '\n');
1030   if (pt != NULL && *(pt+1) == '\0') *pt = '\0';
1031 
1032   pt = tmpbuf;
1033   startpt = tmpbuf;
1034   for (pt = tmpbuf; *pt != '\0'; pt++) {
1035     if (*pt == '\n') {
1036       /* flush this as a single line */
1037       *pt = '\0';
1038       add_line(&data, startpt);
1039       *pt = 'a'; /* anything non-null */
1040       startpt = pt + 1;
1041     }
1042   }
1043   add_line(&data, startpt);
1044 #else
1045   pt = tmpbuf;
1046   startpt = tmpbuf;
1047   while (*pt != '\0') {
1048     if (*pt == '\n') {
1049       /* eat trailing newlines */
1050       if (*(pt+1) != '\0') {
1051 	*pt = '\0';
1052 	add_line(&data, startpt);
1053 	startpt = ++pt;
1054       }
1055     }
1056     else pt++;
1057     if (*pt == '\0') add_line(&data, startpt);
1058   }
1059 #endif
1060   XtFree(tmpbuf);
1061 }
1062 
X_display_cell(char * buf)1063 void X_display_cell(char *buf)
1064 {
1065   /* should be the same as X_display_line above */
1066   add_line(&cells, buf);
1067 }
1068 
1069 
load_file(text_data * data,char * filename)1070 load_file(text_data *data, char *filename)
1071 {
1072   FILE *fp, *fopen();
1073   char buf[MAXLINESIZE];
1074   /* Open the file.  */
1075   if ((fp = fopen(filename, "r")) == NULL) {
1076     fprintf(stderr, "Unable to open %s\n", filename);
1077     exit(1);
1078   }
1079   /* Read each line of the file into the buffer */
1080   while ((fgets(buf, MAXLINESIZE, fp)) != NULL) {
1081     buf[strlen(buf) - 1] = '\0';  /* strip NL at end */
1082     add_line(data, buf);
1083   }
1084 
1085   /* Close the file.  */
1086   fclose(fp);
1087 }
1088 
1089 
1090 
1091 
load_cells(text_data * cells)1092 load_cells(text_data *cells)
1093 {
1094   int i;
1095   char buf[MAXLINESIZE];
1096 
1097   i = 0;
1098   for (i = 0; i < 10; i++) {
1099     sprintf(buf, "line %d", i);
1100     add_line(cells, buf);
1101   }
1102 }
1103 
scroll_bar_moved(Widget w,text_data * data,int sliderpos)1104 void scroll_bar_moved(Widget w, text_data *data, int sliderpos)
1105 {
1106   XPoint points[4];
1107   Region region;
1108   int xsrc, ysrc, xdest, ydest;
1109   /* These points are the same for both cases, so set them here.   */
1110   points[0].x = points[3].x = 0;
1111   points[1].x = points[2].x = data->canvas_width;
1112   xsrc = xdest = 0;
1113 
1114 /*  fprintf(stderr,"items = %d; slider pos = %d; lines = %d\n",
1115 	data->nitems, sliderpos, data->canvas_height / data->fontheight); */
1116   if (sliderpos < data->top) {  /* If we are scrolling down... */
1117     ysrc = 0;
1118     /* Convert the slider's position (rows) to pixels. */
1119     ydest = (data->top - sliderpos) * data->fontheight;
1120     /* Limit the destination to the window height. */
1121     if (ydest > data->canvas_height)
1122       ydest = data->canvas_height;
1123     /* Fill in the points array with the bounding box of the area that needs
1124        to be redrawn - that is, the area that is not copied.    */
1125     points[1].y = points[0].y = 0;
1126     points[3].y = points[2].y = ydest + data->fontheight;
1127   } else {                       /* If we are scrolling up... */
1128     ydest = 0;
1129     /* Convert the slider's position (rows) to pixels.  */
1130     ysrc = (sliderpos - data->top) * data->fontheight;
1131     /* Limit the source to the window height.   */
1132     if (ysrc > data->canvas_height)
1133       ysrc = data->canvas_height;
1134     /* Fill in the points array with the bounding box of the area that needs
1135        to be redrawn.  This area cannot be copied and must be redrawn.    */
1136     points[1].y = points[0].y = data->canvas_height - ysrc;
1137     points[2].y = points[3].y = data->canvas_height;
1138   }
1139   /* Set the top line of the text buffer.  */
1140   data->top = sliderpos;
1141   /* Copy the scrolled region to its new position.   */
1142   XCopyArea(XtDisplay(data->canvas), XtWindow(data->canvas),
1143 	    XtWindow(data->canvas), data->gcread, xsrc, ysrc,
1144 	    data->canvas_width, data->canvas_height, xdest, ydest);
1145   /* Clear the remaining area of any old text.   */
1146   XClearArea(XtDisplay(w), XtWindow(data->canvas), points[0].x, points[0].y,
1147 	     0, points[2].y - points[0].y, 0);
1148   /* Create a region from the points array, and call the XtNexpose callback
1149      with the calculated region as call_data.   */
1150   region = XPolygonRegion(points, 4, EvenOddRule);
1151   XtCallCallbacks(data->canvas, XtNexpose, region);
1152   /* Free the region.  */
1153   XDestroyRegion(region);
1154 }
1155 
1156 /******************************************************
1157  * slider.c: utility to make slider move to the sprite
1158  *           location when clicking the background of
1159  *           a scrollbar widget.
1160  ******************************************************/
1161 
slider_selected(Widget w,caddr_t ignore,int sliderpos)1162 void slider_selected(Widget w, caddr_t ignore, int sliderpos)
1163 {
1164   Arg Args[1];
1165   /* Move the slider bar to the selected point.   */
1166   XtSetArg(Args[0], XtNsliderOrigin, sliderpos);
1167   XtSetValues(w, Args, 1);
1168   /* Call the callback list for XtNsliderMoved to
1169      alter the colors appropriately.  */
1170   XtCallCallbacks(w, XtNsliderMoved, sliderpos);
1171 }
1172 
1173 
create_scrollbar(Widget parent,text_data * data)1174 create_scrollbar(Widget parent, text_data *data)
1175 {
1176   int n = 0;
1177   Arg Args[10];
1178 
1179   n = 0;
1180 #ifdef INTERNAL_ARGS
1181   XtSetArg(Args[n], XtNyResizable, (XtArgVal)True); n++;
1182   XtSetArg(Args[n], XtNyAttachBottom, (XtArgVal)True); n++;
1183   XtSetArg(Args[n], XtNxResizable, (XtArgVal)True); n++;
1184   XtSetArg(Args[n], XtNxRefName, (XtArgVal)"scrollbar"); n++;
1185   XtSetArg(Args[n], XtNxAddWidth, (XtArgVal)True); n++;
1186   XtSetArg(Args[n], XtNxAttachRight, (XtArgVal)True); n++;
1187 #endif
1188 
1189   data->scrollbar = XtCreateManagedWidget("scrollbar", XwscrollbarWidgetClass,
1190 					  parent, NULL, 0);
1191   XtAddCallback(data->scrollbar, XtNsliderMoved, scroll_bar_moved, data);
1192   XtAddCallback(data->scrollbar, XtNareaSelected, slider_selected, data);
1193 
1194   /* Scrollbar movements are reported in terms of lines of text.  */
1195   n = 0;
1196   XtSetArg(Args[n], XtNsliderMin, 0); n++;
1197   XtSetArg(Args[n], XtNsliderMax, 2*(data->nitems)); n++;
1198   XtSetArg(Args[n], XtNsliderOrigin, data->top); n++;
1199   XtSetArg(Args[n], XtNsliderExtent, data->nitems); n++;
1200   XtSetValues(data->scrollbar, Args, n);
1201 }
1202 
1203 
refresh(text_data * data)1204 void refresh(text_data *data)
1205 {
1206   /* redraw the data window, setting the valuator as required
1207      to put the last line at the bottom */
1208 
1209   int lines;
1210   Arg Args[8];
1211   int n;
1212   int bottom_of_screen, slider_size;
1213   XPoint points[4];
1214   Region region;
1215 
1216   lines = 1;
1217   if (data->fontheight == 0) bottom_of_screen = 0;
1218   else {
1219     lines = data->canvas_height / data->fontheight;
1220 
1221     if (lines > data->nitems) data->top = 0;
1222     else
1223       if (data->nitems - data->top > lines) data->top = data->nitems - lines;
1224 
1225     /* scrollbar movements are reported in terms of lines of text.  */
1226 
1227     bottom_of_screen = data->nitems - (data->canvas_height / data->fontheight);
1228     if (bottom_of_screen <= 0) bottom_of_screen = 0;
1229   }
1230   /* fprintf(stderr,"bottom of screen = %d\n",bottom_of_screen); */
1231 
1232   /* set up the valuator */
1233   n = 0;
1234   XtSetArg(Args[n], XtNsliderMin, 0); n++;
1235   XtSetArg(Args[n], XtNsliderMax, bottom_of_screen + lines); n++;
1236   XtSetArg(Args[n], XtNsliderOrigin, data->top); n++;
1237   XtSetArg(Args[n], XtNsliderExtent, lines); n++;
1238   XtSetValues(data->scrollbar, Args, n);
1239 
1240   /* Redraw the entire canvas */
1241   points[0].x = points[3].x = 0;
1242   points[1].x = points[2].x = data->canvas_width;
1243   points[1].y = points[0].y = 0;
1244   points[2].y = points[3].y = data->canvas_height;
1245 
1246   /* Clear the remaining area of any old text.  */
1247   XClearArea(XtDisplay(data->canvas), XtWindow(data->canvas),
1248 	     points[0].x, points[0].y,  0, points[2].y - points[0].y, 0);
1249   /* Create a region from the points array, and call the XtNexpose callback
1250      with the calculated region as call_data.   */
1251   region = XPolygonRegion(points, 4, EvenOddRule);
1252   XtCallCallbacks(data->canvas, XtNexpose, region);
1253   /* Free the region.  */
1254   XDestroyRegion(region);
1255 }
1256 
X_display_refresh(void)1257 void X_display_refresh(void)
1258 {
1259   if (toplevel == NULL) return;
1260   refresh(&cells);
1261   refresh(&data);
1262 }
1263 
X_clear_display(void)1264 void X_clear_display(void)
1265 {
1266   int i;
1267 
1268   for (i = 0; i < data.nitems; i++) XtFree(data.chars[i]);
1269   data.top = data.nitems = 0;
1270   refresh(&data);
1271 }
1272 
X_clear_cell(void)1273 void X_clear_cell(void)
1274 {
1275   int i;
1276 
1277   for (i = 0; i < cells.nitems; i++) XtFree(cells.chars[i]);
1278   cells.top = cells.nitems = 0;
1279   refresh(&cells);
1280 }
1281 
create_gcs(text_data * data)1282 create_gcs(text_data *data)
1283 {
1284   XGCValues gcv;
1285   Display *dpy = XtDisplay(data->canvas);
1286   Window w = XtWindow(data->canvas);
1287   int mask = GCFont | GCForeground | GCBackground;
1288   int read_only_mask = GCForeground | GCBackground;
1289   /* Create two graphics contexts.  One is modifiable, one is read only.  */
1290   gcv.foreground = data->foreground;
1291   gcv.background = data->background;
1292   gcv.font = data->font->fid;
1293   data->gc = XCreateGC(dpy, w, mask, &gcv);
1294   data->gcread = XtGetGC(data->canvas, read_only_mask, &gcv);
1295 }
1296 
1297 
handle_exposures(Widget w,text_data * data,Region region)1298 void handle_exposures(Widget w, text_data *data, Region region)
1299 {
1300   int yloc = 0, index = data->top;
1301   /* Set the clip mask of the GC. */
1302   XSetRegion(XtDisplay(w), data->gc, region);
1303   /* Loop through each line until the bottom of the   window is reached,
1304      or we run out of lines.  Redraw lines that intersect the exposed region */
1305   while (index < data->nitems && yloc < data->canvas_height) {
1306     yloc += data->fontheight;
1307     if (XRectInRegion(region, 0, yloc - data->fontheight, data->canvas_width,
1308 		      data->fontheight) != RectangleOut)
1309       XDrawImageString(XtDisplay(w), XtWindow(w), data->gc, MARGIN, yloc,
1310 		       data->chars[index], data->ll[index]);
1311     index++;
1312   }
1313 }
1314 
1315 
getsize(Widget w,text_data * data,caddr_t call_data)1316 void getsize(Widget w, text_data *data, caddr_t call_data)
1317 {
1318   Arg Args[2];
1319 
1320   XtSetArg(Args[0], XtNheight, &data->canvas_height);
1321   XtSetArg(Args[1], XtNwidth, &data->canvas_width);
1322   XtGetValues(w, Args, 2);
1323 }
1324 
1325 
1326 /***********************************************************
1327  * one_line.c: Create a single line editable text field
1328  ***********************************************************/
1329 
1330 /* Just ring the terminal bell. */
beep(Widget w,XEvent * event,String * params,int num_params)1331 static void beep(Widget w, XEvent *event, String *params, int num_params)
1332 {
1333   /* XBell(XtDisplay(w), 100); */
1334 }
1335 
1336 /* Associate the action "beep" with the function. */
1337 static XtActionsRec actionsTable[] = {
1338   { "beep", beep },
1339 };
1340 /*
1341  * Override all translations that enter a newline.
1342  */
1343 static char defaultTranslations[] =
1344   "Ctrl<Key>J:           beep() \n\
1345    Ctrl<Key>O:           beep() \n\
1346    Ctrl<Key>M:           beep() \n\
1347    <Key> Return:         beep()";
1348 
create_one_line_text_widget(char * name,Widget parent)1349 Widget create_one_line_text_widget(char *name, Widget parent)
1350 {
1351   XFontStruct *font;
1352   Widget w;
1353   Arg Args[1];
1354   XtTranslations trans_table;
1355   /* Add the actions and compile the translations.  */
1356   XtAddActions(actionsTable, XtNumber(actionsTable));
1357   trans_table = XtParseTranslationTable(defaultTranslations);
1358   /* Create a TextEdit widget. */
1359   XtSetArg(Args[0], XtNeditType, XwtextEdit);
1360   w = XtCreateManagedWidget(name, XwtexteditWidgetClass, parent, Args, 1);
1361   /* Install our translations. */
1362   XtOverrideTranslations(w, trans_table);
1363   /* Get the font used by the widget.  */
1364   XtSetArg(Args[0], XtNfont, &font);
1365   XtGetValues(w, Args, 1);
1366   /* Set the widget height according to the font height.  */
1367 #define FONTHEIGHT(f)  ((f)->max_bounds.ascent + (f)->max_bounds.descent)
1368 
1369   XtSetArg(Args[0], XtNheight, FONTHEIGHT(font) + 6);
1370   XtSetValues(w, Args, 1);
1371 
1372   return(w);
1373 }
1374 
1375 /**************************************************************************/
1376 
create_menu_manager(Widget parent,char * mgrname)1377 Widget create_menu_manager(Widget parent, char *mgrname)
1378 {
1379   Widget shell = XtCreatePopupShell(mgrname, shellWidgetClass, parent, NULL,0);
1380   Widget menu_mgr =
1381     XtCreateManagedWidget(mgrname, XwpopupmgrWidgetClass, shell, NULL, 0);
1382   return(menu_mgr);
1383 }
1384 
1385 
create_pane(Widget mgr,char * mgrname,char * name,menu_struct * menulist,int nitems)1386 void create_pane(Widget mgr, char *mgrname, char *name,
1387 		 menu_struct *menulist, int nitems)
1388 {
1389   Arg Args[1];
1390   Widget menupane, pane_shell;
1391   int i;
1392   WidgetList buttons;
1393   /* Allocate a widget list to hold all button widgets.  */
1394   buttons = (WidgetList) XtMalloc(nitems * sizeof(Widget));
1395   /* Create a popup shell to hold this pane.  */
1396   pane_shell = XtCreatePopupShell("pane_shell", shellWidgetClass, mgr,
1397 				  NULL, 0);
1398   /* Create a Cascade menu pane, and attach it to the given menu manager.   */
1399   XtSetArg(Args[0], XtNattachTo, (XtArgVal) mgrname);
1400   menupane = XtCreateManagedWidget(name, XwcascadeWidgetClass, pane_shell,
1401 				   Args, 1);
1402   /* Create a menu button for each item in the menu.  */
1403   for (i = 0; i < nitems; i++) {
1404     buttons[i] = XtCreateWidget(menulist[i].name, XwmenubuttonWidgetClass,
1405 				menupane, NULL, 0);
1406     XtAddCallback(buttons[i], XtNselect, menulist[i].func, menulist[i].data);
1407   }
1408   /* Manage all button widgets.   */
1409   XtManageChildren(buttons, nitems);
1410 }
1411 
1412 
1413 /*******************************************************
1414   Popup widgetry -- not currently used, but good to have around
1415 *********************************************************/
1416 
1417 
1418 static char *fields[] = { "field1", "field2", "field3" };
1419 static char *labels[] = { "label1", "label2", "label3" };
1420 
pop_it_down(Widget w,caddr_t client_data,caddr_t call_data)1421 void pop_it_down(Widget w, caddr_t client_data, caddr_t call_data)
1422 {
1423   Widget bb, shell;
1424 
1425   bb = XtParent(w);
1426   shell = XtParent(bb);
1427 
1428   XtPopdown(shell);
1429   XtDestroyWidget(shell);
1430 }
1431 
1432 
create_filename_editor(Widget parent)1433 Widget create_filename_editor(Widget parent)
1434 {
1435   Widget bb, popup, button;
1436 
1437   popup =
1438     XtCreatePopupShell ("popup", overrideShellWidgetClass, parent,  NULL, 0);
1439   /* Create a BulletinBoard widget to hold the fields.  */
1440   bb = XtCreateManagedWidget("board", XwbulletinWidgetClass, popup, NULL, 0);
1441 
1442   /* Create a "done" button and register a popdown callback.  */
1443   button = XtCreateManagedWidget("done", XwpushButtonWidgetClass, bb, NULL, 0);
1444   XtAddCallback(button, XtNrelease, pop_it_down, NULL);
1445 
1446   create_one_line_text_widget("field1",bb);
1447   return popup;
1448 }
1449 
1450 
pop_it_up(Widget w,caddr_t client_data,caddr_t call_data)1451 void pop_it_up(Widget w, caddr_t client_data, caddr_t call_data)
1452 {
1453   Widget shell;
1454   Window root, child;
1455   int root_x, root_y, win_x, win_y, mask;
1456 
1457   XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &root_x,
1458 		&root_y, &win_x, &win_y, &mask);
1459 
1460   shell = create_filename_editor(w);
1461 
1462   XtRealizeWidget(shell);
1463   XtMoveWidget(shell, root_x - 30, root_y - 20);
1464 
1465   XtPopup(shell, XtGrabExclusive);
1466 }
1467 
1468 /*********************************************************************/
1469 
label_widget(Widget parent,char * string)1470 Widget label_widget(Widget parent, char *string)
1471 {
1472   Arg Args[10];
1473   int n;
1474 
1475   n = 0;
1476   XtSetArg(Args[n], XtNstring, string); n++;
1477   return XtCreateManagedWidget
1478     ("label", XwstatictextWidgetClass, parent, Args, n);
1479 }
1480 
1481 static jmp_buf jmpenv;
1482 
handler()1483 static void handler()
1484 /* static void handler(int sig) */
1485 {
1486   Fprintf(stderr,"\nInterrupt!!\n");
1487   Fflush(stderr);
1488   X_END();
1489   longjmp(jmpenv,1);
1490 }
1491 
1492 
1493 static XrmOptionDescRec opTable[] = {
1494 {"-sadfa","Netgen*yResizable", XrmoptionNoArg,	(caddr_t) "True"},
1495 {"-sszyys","Netgen*yAttachBottom", XrmoptionNoArg, (caddr_t) "True"},
1496 };
1497 
1498 /*char datastring[] = "*yResizable: True\n*yAttachBottom: True";*/
1499 char datastring[] = "*yAttachBottom: True";
1500 
1501 /*
1502 Fileview*canvas.xRefName:	scrollbar
1503 Fileview*canvas.xResizable:	True
1504 Fileview*canvas.xAddWidth:	True
1505 Fileview*canvas.xAttachRight:	True
1506 Fileview*canvas.yAttachTop:	True
1507 */
1508 
X_main_loop(int argc,char * argv[])1509 void X_main_loop(int argc, char *argv[])
1510 {
1511   /* toplevel widget is global */
1512   Widget pane, frame, cells_frame, menu_mgr, title, data_entry;
1513   Arg Args[10];
1514   int n;
1515   XrmDatabase rdb;
1516 
1517 
1518   /* if we're not using X, just call good old Query(); */
1519   if (getenv("DISPLAY") == NULL) {
1520     Query();
1521     return;
1522   }
1523 
1524 /* Xnetgen used to be Fileview */
1525 #ifdef INCLUDE_FALLBACK
1526   XtAppContext app_con;
1527   toplevel = XtAppInitialize(&app_con, "NewNetgen", NULL, 0,
1528 			     &argc, argv, fallback_resources, NULL, 0);
1529 #else
1530   toplevel = XtInitialize(argv[0], "Netgen",
1531 			  opTable, XtNumber(opTable), &argc, argv);
1532 #endif
1533 
1534 
1535   rdb = XrmGetStringDatabase(datastring);
1536   if (rdb != NULL)
1537     XrmMergeDatabases(rdb, &((XtDisplay(toplevel))->db));
1538 
1539   XtGetApplicationResources
1540     (toplevel, &data, resources, XtNumber(resources), NULL, 0);
1541   /* Read the file specified in argv[1] into the text buffer.  */
1542 #if 0
1543   load_file(&data, (argc == 2) ? argv[1] : NULL);
1544 #else
1545   X_display_line("Netgen" NETGEN_VERSION "." NETGEN_REVISION);
1546 #endif
1547 
1548   XtGetApplicationResources
1549     (toplevel, &cells, resources, XtNumber(resources), NULL, 0);
1550 #if 0
1551   load_cells(&cells);
1552 #else
1553   X_display_line("Netgen" NETGEN_VERSION "." NETGEN_REVISION);
1554 #endif
1555 
1556   n = 0;
1557 #ifdef INTERNAL_ARGS
1558   XtSetArg(Args[n], XtNyResizable, (XtArgVal)True); n++;
1559   XtSetArg(Args[n], XtNyAttachBottom, (XtArgVal)True); n++;
1560   XtSetArg(Args[n], XtNxResizable, (XtArgVal)True); n++;
1561   XtSetArg(Args[n], XtNxRefName, (XtArgVal)"scrollbar"); n++;
1562   XtSetArg(Args[n], XtNxAddWidth, (XtArgVal)True); n++;
1563   XtSetArg(Args[n], XtNxAttachRight, (XtArgVal)True); n++;
1564 #endif
1565   /* Create a VPane widget as a base to allow children to be resized easily. */
1566   pane = XtCreateManagedWidget("pane", XwvPanedWidgetClass, toplevel, Args, n);
1567 
1568   /* create a top command and title area */
1569   title = label_widget(pane, NETGEN_VERSION);
1570 
1571 
1572   /* create data entry area in the form of a RowCol widget */
1573   n = 0;
1574   XtSetArg(Args[0], XtNcolumns, 2); n++;
1575   data_entry = XtCreateManagedWidget("rowcol",XwrowColWidgetClass,pane,Args,n);
1576 
1577   label_widget(data_entry, "File name:");
1578   GlobalFileWidget = create_one_line_text_widget("field1", data_entry);
1579 
1580   label_widget(data_entry, "Cell name:");
1581   GlobalCellWidget = create_one_line_text_widget("field1", data_entry);
1582 
1583   label_widget(data_entry, "Element:");
1584   GlobalDataWidget = create_one_line_text_widget("field1", data_entry);
1585 
1586   label_widget(data_entry, "2nd cell/elem:");
1587   GlobalOtherWidget = create_one_line_text_widget("field1", data_entry);
1588 
1589 
1590 #ifdef CELL_LIST_MENU
1591   /* create the top cell list area */
1592 
1593   n = 0;
1594   cells_frame = XtCreateManagedWidget
1595     ("framework", XwformWidgetClass, pane, Args, n);
1596   create_scrollbar(cells_frame, &cells);
1597 
1598   /* Create the drawing surface.  */
1599   n = 0;
1600   XtSetArg(Args[n], XtNwidth, (XtArgVal)500); n++;
1601   XtSetArg(Args[n], XtNheight, (XtArgVal)100); n++;
1602   cells.canvas = XtCreateManagedWidget
1603     ("canvas", XwworkSpaceWidgetClass, cells_frame, Args, n);
1604   XtAddCallback(cells.canvas, XtNexpose, handle_exposures, &cells);
1605   XtAddCallback(cells.canvas, XtNresize, getsize, &cells);
1606 #endif
1607 
1608   /* create the viewing area */
1609   n = 0;
1610 #ifdef INTERNAL_ARGS
1611   XtSetArg(Args[n], XtNyResizable, (XtArgVal)True); n++;
1612   XtSetArg(Args[n], XtNyAttachBottom, (XtArgVal)True); n++;
1613   XtSetArg(Args[n], XtNxResizable, (XtArgVal)True); n++;
1614   XtSetArg(Args[n], XtNxRefName, (XtArgVal)"scrollbar"); n++;
1615   XtSetArg(Args[n], XtNxAddWidth, (XtArgVal)True); n++;
1616   XtSetArg(Args[n], XtNxAttachRight, (XtArgVal)True); n++;
1617 #endif
1618 /*  XtSetArg(Args[n], XtNxAttachTop, (XtArgVal)True); n++; */
1619   frame = XtCreateManagedWidget("framework", XwformWidgetClass, pane, Args, n);
1620   create_scrollbar(frame, &data);
1621 
1622   /* Create the drawing surface.  */
1623   n = 0;
1624   XtSetArg(Args[n], XtNwidth, (XtArgVal)500); n++;
1625   XtSetArg(Args[n], XtNheight, (XtArgVal)400); n++;
1626 
1627 #ifdef INTERNAL_ARGS
1628   XtSetArg(Args[n], XtNyResizable, (XtArgVal)True); n++;
1629   XtSetArg(Args[n], XtNyAttachBottom, (XtArgVal)True); n++;
1630   XtSetArg(Args[n], XtNxResizable, (XtArgVal)True); n++;
1631   XtSetArg(Args[n], XtNxRefName, (XtArgVal)"scrollbar"); n++;
1632   XtSetArg(Args[n], XtNxAddWidth, (XtArgVal)True); n++;
1633   XtSetArg(Args[n], XtNxAttachRight, (XtArgVal)True); n++;
1634 #endif
1635   data.canvas = XtCreateManagedWidget
1636     ("canvas", XwworkSpaceWidgetClass, frame, Args, n);
1637   XtAddCallback(data.canvas, XtNexpose, handle_exposures, &data);
1638   XtAddCallback(data.canvas, XtNresize, getsize, &data);
1639 
1640 
1641   /* Create the menu manager.  */
1642   menu_mgr = create_menu_manager(title, "menu_mgr");
1643   /* Create the Main menu pane. */
1644   create_pane(menu_mgr, "menu_mgr", "Netgen Main Menu", Menu,
1645 	      ItemsInMenu(Menu));
1646   /* Create sub menus for various items on the main menu.  */
1647   create_pane(menu_mgr, "Print", "PRINT menu", PrintMenu,
1648 	      ItemsInMenu(PrintMenu));
1649   create_pane(menu_mgr, "Write cell", "WRITE menu", WriteMenu,
1650 	      ItemsInMenu(WriteMenu));
1651   create_pane(menu_mgr, "Read cell", "READ menu", ReadMenu,
1652 	      ItemsInMenu(ReadMenu));
1653   create_pane(menu_mgr, "NETCMP", "NETCMP menu", NetcmpMenu,
1654 	      ItemsInMenu(NetcmpMenu));
1655   create_pane(menu_mgr, "PROTOCHIP", "PROTOCHIP menu", ProtoMenu,
1656 	      ItemsInMenu(ProtoMenu));
1657   /* Create sub-sub menus for Protochip sub-menu */
1658   create_pane(menu_mgr, "Embed cell", "EMBED Algorithm", ProtoEmbedMenu,
1659 	      ItemsInMenu(ProtoEmbedMenu));
1660   create_pane(menu_mgr, "PROTOCHIP parameters", "PROTOCHIP Parameters",
1661 	      ProtoConstMenu, ItemsInMenu(ProtoConstMenu));
1662 
1663   XtRealizeWidget(toplevel);
1664 
1665   /* Create the graphics contexts after realizing the widgets
1666      because create_gcs requires a valid window ID.   */
1667   create_gcs(&data);
1668   create_gcs(&cells);
1669 
1670   /* a little magic to initialize all windows to bottom */
1671   getsize(cells.canvas, &cells, NULL);
1672   scroll_bar_moved(cells.scrollbar, &cells, 0);
1673   refresh(&cells);
1674 
1675   getsize(data.canvas, &data, NULL);
1676   scroll_bar_moved(data.scrollbar, &data, 0);
1677   refresh(&data);
1678 
1679 #ifdef INCLUDE_FALLBACK
1680   XtAppMainLoop(app_con);
1681 #else
1682   /* install a vector to trap ^C */
1683   setjmp(jmpenv);
1684   signal(SIGINT,handler);
1685   XtMainLoop();
1686 #endif
1687 }
1688 
1689 #endif /* X11_HP_WIDGETS */
1690 
1691 #ifdef X11_MOTIF_WIDGETS
1692 
1693 /*************************************/
1694 /*    MOTIF widget code              */
1695 /*************************************/
1696 
1697 /* define the following for scrolled text windows */
1698 #undef USE_SCROLLING_TEXT
1699 
1700 #include <Xm/Xm.h>
1701 #include <Xm/List.h>
1702 #include <Xm/Text.h>
1703 #include <Xm/PanedW.h>
1704 #include <Xm/Label.h>
1705 #include <Xm/RowColumn.h>
1706 #include <Xm/PushB.h>
1707 #include <Xm/SelectioB.h>
1708 
1709 XmStringCharSet cs = "ISOLatin1";
1710 
1711 static char prompt_response[100];
1712 int prompt_done;
1713 int calling_editor;  /* which string are we trying to get ? */
1714 #define FILE_NAME 1
1715 #define CELL_NAME 2
1716 #define OTHER_NAME 3
1717 #define DATA_NAME 4
1718 
prompt_callback(Widget w,caddr_t closure,caddr_t call_data)1719 void prompt_callback(Widget w, caddr_t closure, caddr_t call_data)
1720 {
1721   char *c;
1722   XmSelectionBoxCallbackStruct *cb = (XmSelectionBoxCallbackStruct *)call_data;
1723 
1724   XmStringGetLtoR(cb->value, cs, &c);
1725   strcpy(prompt_response, c);
1726   XtFree(c);
1727   prompt_done = 1;
1728 }
1729 
prompt_cancel_callback(Widget w,caddr_t closure,caddr_t call_data)1730 void prompt_cancel_callback(Widget w, caddr_t closure, caddr_t call_data)
1731 {
1732   *prompt_response = '\0';
1733   prompt_done = 1;
1734 }
1735 
prompt_save_callback(Widget w,caddr_t closure,caddr_t call_data)1736 void prompt_save_callback(Widget w, caddr_t closure, caddr_t call_data)
1737 {
1738   prompt_callback(w, closure, call_data);
1739   /* now we need to save the data in the original editor window */
1740   switch (calling_editor) {
1741   case FILE_NAME:
1742     XmTextSetString(GlobalFileWidget, prompt_response);
1743     break;
1744   case CELL_NAME:
1745     XmTextSetString(GlobalCellWidget, prompt_response);
1746     break;
1747   case OTHER_NAME:
1748     XmTextSetString(GlobalOtherWidget, prompt_response);
1749     break;
1750   case DATA_NAME:
1751     XmTextSetString(GlobalDataWidget, prompt_response);
1752     break;
1753   }
1754 }
1755 
DialogWidget(char * prompt)1756 char *DialogWidget(char *prompt)
1757 {
1758   Widget w;
1759   Arg Args[10];
1760   int n;
1761 
1762   *prompt_response = '\0';
1763   prompt_done = 0;
1764   n = 0;
1765   XtSetArg(Args[n], XmNselectionLabelString,
1766 	   XmStringCreateLtoR(prompt, cs)); n++;
1767   XtSetArg(Args[n], XmNdialogType, XmDIALOG_PROMPT); n++;
1768   XtSetArg(Args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
1769   XtSetArg(Args[n], XmNautoUnmanage, True); n++;
1770   XtSetArg(Args[n], XmNhelpLabelString, XmStringCreateLtoR("Save", cs)); n++;
1771 
1772   XtSetArg(Args[n], XmNminHeight, 100); n++;
1773   XtSetArg(Args[n], XmNminWidth, 100); n++;
1774 
1775   w = XmCreatePromptDialog(toplevel, "prompt", Args, n);
1776   XtAddCallback(w, XmNokCallback, prompt_callback, NULL);
1777   XtAddCallback(w, XmNcancelCallback, prompt_cancel_callback, NULL);
1778   XtAddCallback(w, XmNhelpCallback, prompt_save_callback, NULL);
1779   XtManageChild(w);
1780 
1781   /* we want the application to WAIT for any callback */
1782   while (!prompt_done)
1783     XtProcessEvent(XtIMAll);
1784 
1785   return(prompt_response);
1786 }
1787 
get_something(char * buf,Widget w,char * prompt)1788 char *get_something(char *buf, Widget w, char *prompt)
1789 {
1790   char *c;
1791 
1792   if (strlen(buf)) return(buf);
1793 
1794   c = XmTextGetString(w);
1795   strcpy(buf, c);
1796   XtFree(c);
1797   if (strlen(buf) == 0) {
1798     /* bring up a dialog widget to get the filename */
1799     strcpy(buf, DialogWidget(prompt));
1800   }
1801   return (buf);
1802 }
1803 
get_file(void)1804 char *get_file(void)
1805 {
1806   calling_editor = FILE_NAME;
1807   return(get_something(GlobalFileName, GlobalFileWidget, "Enter File Name"));
1808 }
1809 
get_cell(void)1810 char *get_cell(void)
1811 {
1812   calling_editor = CELL_NAME;
1813   return(get_something(GlobalCellName, GlobalCellWidget, "Enter Cell Name"));
1814 }
1815 
get_other(void)1816 char *get_other(void)
1817 {
1818   calling_editor = OTHER_NAME;
1819   return(get_something(GlobalOtherName, GlobalOtherWidget, "Enter Name"));
1820 }
1821 
get_data(void)1822 char *get_data(void)
1823 {
1824   calling_editor = DATA_NAME;
1825   return(get_something(GlobalDataName, GlobalDataWidget, "Enter Data"));
1826 }
1827 
1828 
1829 Widget pane, frame, cells_frame, menu_mgr, title, data_entry;
1830 
1831 #define DATABUFSIZ 4000
1832 
1833 char data_buf[DATABUFSIZ];
1834 char *data_endptr = data_buf;
1835 
X_display_line(char * buf)1836 void X_display_line(char *buf)
1837 {
1838   if (toplevel == NULL) {
1839     /* not using X windows */
1840     printf("%s", buf);
1841     return;
1842   }
1843 
1844   if (data_endptr + strlen(buf) > data_buf + DATABUFSIZ) {
1845     char *cp;
1846     /* find the next line */
1847     cp = data_buf + strlen(buf);
1848     while (*cp != '\n' && cp < data_endptr) cp++;
1849 
1850     memcpy(data_buf, cp, data_endptr - cp + 1);
1851     data_endptr -= (cp - data_buf);
1852   }
1853   /* now just copy the string */
1854   strcpy(data_endptr, buf);
1855   data_endptr += strlen(buf);
1856   memset(data_endptr, 0, data_buf + DATABUFSIZ - data_endptr - 1);
1857 }
1858 
1859 #ifdef USE_SCROLLED_TEXT
X_display_refresh(void)1860 void X_display_refresh(void)
1861 {
1862   Arg Args[10];
1863   int n;
1864 
1865   short lines;
1866   char *cp;
1867   XmTextPosition offset, cursor;
1868   Boolean showcur;
1869 
1870   if (toplevel == NULL) return;
1871 
1872   n = 0;
1873   XtSetArg(Args[n], XmNrows, &lines); n++;
1874   XtSetArg(Args[n], XmNtopPosition, &offset); n++;
1875   XtSetArg(Args[n], XmNcursorPosition, &cursor); n++;
1876   XtSetArg(Args[n], XmNautoShowCursorPosition, &showcur); n++;
1877   XtGetValues(frame, Args, n);
1878   printf("Before: %d lines in the display, %ld chars offset %ld cursor (showing %d)\n",
1879 	 (int)lines, (long)offset, (long)cursor, (int)showcur);
1880 
1881   cp = data_endptr;
1882   while (cp > data_buf && lines > 0)
1883     if (*cp-- == '\n') lines--;
1884 
1885 printf("lines = %d, cp = %p, data_buf = %p\n", (int)lines, cp, data_buf);
1886   if (lines == 0) cp++;
1887   if (cp < data_buf) cp = data_buf;
1888 
1889   /* set the editor to display the string */
1890   n = 0;
1891   XtSetArg(Args[n], XmNvalue, data_buf); n++;
1892 #if 0
1893   printf("Setting offset to %d\n", (int)((XmTextPosition)(cp - data_buf)));
1894   XtSetArg(Args[n], XmNtopPosition, (XmTextPosition)(cp - data_buf)); n++;
1895 /*  XtSetArg(Args[n], XmNtopPosition, (XmTextPosition)5); n++; */
1896 #else
1897   XtSetArg(Args[n], XmNautoShowCursorPosition, (XtArgVal)True); n++;
1898   printf("Setting cursor position to %d\n",
1899 	 (int)((XmTextPosition)(data_endptr - data_buf)));
1900   XtSetArg(Args[n], XmNcursorPosition,
1901 	   (XmTextPosition)(data_endptr - data_buf)); n++;
1902 #endif
1903 
1904   XtSetValues(frame, Args, n);
1905 
1906   n = 0;
1907   XtSetArg(Args[n], XmNrows, &lines); n++;
1908   XtSetArg(Args[n], XmNtopPosition, &offset); n++;
1909   XtSetArg(Args[n], XmNcursorPosition, &cursor); n++;
1910   XtGetValues(frame, Args, n);
1911   printf("After: %d lines in the display, %ld chars offset %ld cursor\n",
1912 	 (int)lines, (long)offset, (long)cursor);
1913 }
1914 #else /* not USE_SCROLLED_TEXT */
1915 
X_display_refresh(void)1916 void X_display_refresh(void)
1917 /* very simple code that scrolls the window as required */
1918 {
1919   Arg Args[10];
1920   int n;
1921 
1922   short lines;
1923   char *cp;
1924 
1925   if (toplevel == NULL) return;
1926 
1927   n = 0;
1928   XtSetArg(Args[n], XmNrows, &lines); n++;
1929   XtGetValues(frame, Args, n);
1930 
1931   cp = data_endptr;
1932   while (cp > data_buf && lines > 0)
1933     if (*cp-- == '\n') lines--;
1934 
1935   if (lines == 0) cp++;
1936   if (cp < data_buf) cp = data_buf;
1937 
1938   /* set the editor to display the string */
1939   n = 0;
1940   XtSetArg(Args[n], XmNvalue, cp); n++;
1941   XtSetValues(frame, Args, n);
1942 }
1943 
1944 #endif /* not USE_SCROLLED_TEXT */
1945 
1946 
1947 
menu_index_by_menu(menu_struct * mp)1948 int menu_index_by_menu(menu_struct *mp)
1949 {
1950   int i;
1951   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
1952     if (MenuArray[i].menu == mp) return(i);
1953 printf("menu_index_by_menu: this should never happen\n");
1954   return(0);
1955 }
1956 
1957 
menu_index_by_widget(Widget w)1958 int menu_index_by_widget(Widget w)
1959 {
1960   int i;
1961   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
1962     if (MenuArray[i].widget == w) return(i);
1963   fprintf(stderr,"menu_index_by_widget: this should never happen\n");
1964   return(0);
1965 }
1966 
find_menu_by_widget(Widget w)1967 menu_struct *find_menu_by_widget(Widget w)
1968 {
1969   int i;
1970   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
1971     if (MenuArray[i].widget == w) return(MenuArray[i].menu);
1972   fprintf(stderr,"find_menu_by_widget: this should never happen\n");
1973   return(NULL);
1974 }
1975 
1976 void ActivateMenu(menu_struct *mp);
1977 
MenuCallback(Widget w,caddr_t closure,caddr_t call_data)1978 void MenuCallback(Widget w, caddr_t closure, caddr_t call_data)
1979 {
1980   XmListCallbackStruct *cb = (XmListCallbackStruct *)call_data;
1981   int i, ItemCount;
1982   menu_struct *menu;
1983 
1984   menu = find_menu_by_widget(w);
1985 
1986   ItemCount = ItemsInMenu(menu);
1987   for (i = 0; i < ItemCount; i++) {
1988     char *s;
1989     XmStringGetLtoR(cb->item, cs, &s);
1990     if (!strcmp(s, menu[i].name)) {
1991       /* printf("Trying to run function: %s\n", menu[i].name); */
1992       if (menu[i].submenu != NULL) ActivateMenu(menu[i].submenu);
1993       else (*(menu[i].func))(w, NULL, NULL);
1994       break;
1995     }
1996   }
1997   XmListDeselectAllItems(w);
1998 }
1999 
MenuDestroyCallback(Widget w,caddr_t closure,caddr_t call_data)2000 void MenuDestroyCallback(Widget w, caddr_t closure, caddr_t call_data)
2001 {
2002   int menunum;
2003 
2004   menunum = menu_index_by_widget(w);
2005   MenuArray[menunum].widget = NULL;
2006 }
2007 
make_menu(menu_struct * menu)2008 Widget make_menu(menu_struct *menu)
2009 /* returns the List widget for the menu, NOT the top shell widget */
2010 {
2011   int n;
2012   Arg Args[20];
2013   Widget top, widget;
2014   XmString *Items;
2015   int ItemCount;
2016 
2017   top =
2018     XtCreateApplicationShell("menuShell", topLevelShellWidgetClass, NULL, 0);
2019 
2020   ItemCount = ItemsInMenu(menu);
2021   Items = (XmString *)CALLOC(ItemCount, sizeof(XmString));
2022   for (n = 0;  n < ItemCount; n++)
2023     Items[n] = (XmString)XmStringCreateLtoR(menu[n].name, cs);
2024 
2025   n = 0;
2026   XtSetArg(Args[n], XmNitems, (XtArgVal)Items); n++;
2027   XtSetArg(Args[n], XmNitemCount, (XtArgVal)ItemCount); n++;
2028   XtSetArg(Args[n], XmNvisibleItemCount, (XtArgVal)ItemCount); n++;
2029   XtSetArg(Args[n], XmNselectionPolicy, (XtArgVal)XmSINGLE_SELECT); n++;
2030 
2031   XtSetArg(Args[n], XmNlistMarginHeight, (XtArgVal)20); n++;
2032   XtSetArg(Args[n], XmNlistMarginWidth, (XtArgVal)30); n++;
2033   XtSetArg(Args[n], XmNborderWidth, (XtArgVal)10); n++;
2034 
2035   widget = XmCreateList(top,"menu", Args, n);
2036 
2037   XtManageChild(widget);
2038   XtAddCallback(widget, XmNsingleSelectionCallback, MenuCallback, NULL);
2039   XtAddCallback(widget, XmNdestroyCallback, MenuDestroyCallback, NULL);
2040 
2041 #if 0
2042   /* put all menus at a fixed position; this doesn't work for mwm */
2043   n = 0;
2044   XtSetArg(Args[n], XmNx, (XtArgVal)20); n++;
2045   XtSetArg(Args[n], XmNy, (XtArgVal)(30 + 50*menu_index_by_menu(menu))); n++;
2046   XtSetValues(top, Args, n);
2047 #endif
2048 
2049   XtRealizeWidget(top);
2050 
2051   /* put all menus at a fixed position */
2052   n = 0;
2053   XtSetArg(Args[n], XmNx, (XtArgVal)20); n++;
2054   XtSetArg(Args[n], XmNy, (XtArgVal)(30 + 50*menu_index_by_menu(menu))); n++;
2055   XtSetValues(top, Args, n);
2056 
2057   return(widget);
2058 }
2059 
2060 
RaiseMenu(Widget w)2061 void RaiseMenu(Widget w)
2062 {
2063   /* just bring it up; remember to bring up the SHELL, the list's parent !!! */
2064   XMapRaised(XtDisplay(XtParent(w)), XtWindow(XtParent(w)));
2065 }
2066 
ActivateMenu(menu_struct * mp)2067 void ActivateMenu(menu_struct *mp)
2068 /* if it exists, raise it, otherwise create it */
2069 {
2070   int menunum;
2071   Widget w;
2072 
2073   menunum = menu_index_by_menu(mp);
2074   w = MenuArray[menunum].widget;
2075 
2076   if (w != NULL) RaiseMenu(w);
2077   else MenuArray[menunum].widget = make_menu(mp);
2078 }
2079 
2080 
ActivateTopMenuProc(Widget w,caddr_t closure,caddr_t call_data)2081 void ActivateTopMenuProc(Widget w, caddr_t closure, caddr_t call_data)
2082 /* raise all menus that exist, and create the top-level if required */
2083 {
2084   int i;
2085 
2086   for (i = 0; i < sizeof(MenuArray)/sizeof(MenuArray[0]); i++)
2087     if (MenuArray[i].widget != NULL) RaiseMenu(MenuArray[i].widget);
2088 
2089   /* make sure the main menu is raised in any event */
2090   ActivateMenu(Menu);
2091 }
2092 
2093 
2094 
label_widget(Widget parent,char * string)2095 Widget label_widget(Widget parent, char *string)
2096 {
2097   Arg Args[10];
2098   int n;
2099   Widget w;
2100 
2101   n = 0;
2102   XtSetArg(Args[n], XmNlabelString,
2103 	   (XtArgVal)XmStringCreate(string, cs)); n++;
2104   w = XmCreateLabel(parent, "label", Args, n);
2105   XtManageChild(w);
2106   return w;
2107 }
2108 
entry_widget(Widget parent,char * string)2109 Widget entry_widget(Widget parent, char *string)
2110 {
2111   Arg Args[10];
2112   int n;
2113   Widget w;
2114 
2115   n = 0;
2116   XtSetArg(Args[n], XmNeditMode, (XtArgVal)XmSINGLE_LINE_EDIT); n++;
2117   w = XmCreateText(data_entry, "entry", Args, n);
2118   XtManageChild(w);
2119   return w;
2120 }
2121 
text_widget(Widget parent,char * string)2122 Widget text_widget(Widget parent, char *string)
2123 {
2124   Arg Args[10];
2125   int n;
2126   Widget w;
2127 
2128   n = 0;
2129   XtSetArg(Args[n], XmNeditable, (XtArgVal)False); n++;
2130   XtSetArg(Args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
2131 #ifdef USE_SCROLLED_TEXT
2132   XtSetArg(Args[n], XmNscrollHorizontal, (XtArgVal)False); n++;
2133   XtSetArg(Args[n], XmNscrollVertical, (XtArgVal)True); n++;
2134   w = XmCreateScrolledText(parent, string, Args, n);
2135 #else
2136   w = XmCreateText(parent, string, Args, n);
2137 #endif
2138   XtManageChild(w);
2139   return w;
2140 }
2141 
X_main_loop(int argc,char * argv[])2142 void X_main_loop(int argc, char *argv[])
2143 {
2144   /* toplevel widget is global */
2145   Arg Args[10];
2146   int n;
2147 
2148   /* if we're not using X, just call good old Query(); */
2149   if (getenv("DISPLAY") == NULL) {
2150     Query();
2151     return;
2152   }
2153 
2154   toplevel = XtInitialize(argv[0], "Netgen", NULL, 0, &argc, argv);
2155   /* create a vertical pane window to permit children to be resized */
2156   pane = XmCreatePanedWindow(toplevel,"pane",NULL, 0);
2157   XtManageChild(pane);
2158 
2159   /* create a top command and title area */
2160   n = 0;
2161   XtSetArg(Args[n], XmNlabelString,
2162 	   (XtArgVal)XmStringCreate("Netgen" NETGEN_VERSION "." NETGEN_REVISION, cs));
2163   n++;
2164   title = XmCreatePushButton(pane, "title", Args, n);
2165   XtAddCallback(title, XmNactivateCallback, ActivateTopMenuProc, NULL);
2166   XtManageChild(title);
2167 
2168   /* create a data entry area for the four text fields */
2169   n = 0;
2170   XtSetArg(Args[n], XmNnumColumns, 2); n++;
2171   XtSetArg(Args[n], XmNpacking, XmPACK_COLUMN); n++;
2172   data_entry = XmCreateRowColumn(pane, "rowcol", Args, n);
2173   XtManageChild(data_entry);
2174 
2175   /* put 4 labels in the rowcol widget, and four text editors */
2176   label_widget(data_entry, "File Name:");
2177   label_widget(data_entry, "Cell Name:");
2178   label_widget(data_entry, "Element:");
2179   label_widget(data_entry, "2nd cell/elem:");
2180   GlobalFileWidget = entry_widget(data_entry, NULL);
2181   GlobalCellWidget = entry_widget(data_entry, NULL);
2182   GlobalDataWidget = entry_widget(data_entry, NULL);
2183   GlobalOtherWidget = entry_widget(data_entry, NULL);
2184 
2185   /* create two text widgets */
2186   cells_frame = text_widget(pane, "cells");
2187   frame = text_widget(pane, "text");
2188 
2189 /*
2190 Can't change scrolling policy after the window is created
2191   n = 0;
2192   XtSetArg(Args[n], XmNscrollingPolicy, (XtArgVal)XmAUTOMATIC); n++;
2193   XtSetValues(XtParent(frame), Args, n);
2194 */
2195 
2196   XtRealizeWidget(toplevel);
2197   XtMainLoop();
2198 }
2199 #endif /* X11_MOTIF_WIDGETS */
2200 
2201 
2202 
2203 #ifdef X11_ATHENA_WIDGETS
2204 
2205 /*************************************/
2206 /*    ATHENA widget code              */
2207 /*************************************/
2208 
2209 #include <X11/Xaw/Command.h>
2210 #include <X11/Xaw/Paned.h>
2211 #include <X11/Xaw/AsciiText.h>
2212 #include <X11/Xaw/List.h>
2213 #include <X11/Xaw/Label.h>
2214 #include <X11/Xaw/Form.h>
2215 
2216 XtAppContext app_con;
2217 
2218 int calling_editor;  /* which string are we trying to get ? */
2219 #define FILE_NAME 1
2220 #define CELL_NAME 2
2221 #define OTHER_NAME 3
2222 #define DATA_NAME 4
2223 
2224 
get_something(char * buf,Widget w,char * prompt)2225 char *get_something(char *buf, Widget w, char *prompt)
2226 {
2227   Arg Args[10];
2228   int n;
2229 
2230   char *c;
2231 
2232   if (strlen(buf)) return(buf);
2233 
2234   n = 0;
2235   XtSetArg(Args[n], XtNstring, &c); n++;
2236   XtGetValues(w, Args, n);
2237   strcpy(buf, c);
2238   return (buf);
2239 }
2240 
get_file(void)2241 char *get_file(void)
2242 {
2243   calling_editor = FILE_NAME;
2244   return(get_something(GlobalFileName, GlobalFileWidget, "Enter File Name"));
2245 }
2246 
get_cell(void)2247 char *get_cell(void)
2248 {
2249   calling_editor = CELL_NAME;
2250   return(get_something(GlobalCellName, GlobalCellWidget, "Enter Cell Name"));
2251 }
2252 
get_other(void)2253 char *get_other(void)
2254 {
2255   calling_editor = OTHER_NAME;
2256   return(get_something(GlobalOtherName, GlobalOtherWidget, "Enter Name"));
2257 }
2258 
get_data(void)2259 char *get_data(void)
2260 {
2261   calling_editor = DATA_NAME;
2262   return(get_something(GlobalDataName, GlobalDataWidget, "Enter Data"));
2263 }
2264 
2265 
2266 Widget pane, frame, cells_frame, menu_mgr, title, data_entry;
2267 
2268 #define DATABUFSIZ 4000
2269 
2270 char data_buf[DATABUFSIZ];
2271 char *data_endptr = data_buf;
2272 
X_display_line(char * buf)2273 void X_display_line(char *buf)
2274 {
2275   if (toplevel == NULL) {
2276     /* not using X windows */
2277     printf("%s", buf);
2278     return;
2279   }
2280 
2281   if (data_endptr + strlen(buf) > data_buf + DATABUFSIZ) {
2282     char *cp;
2283     /* find the next line */
2284     cp = data_buf + strlen(buf);
2285     while (*cp != '\n' && cp < data_endptr) cp++;
2286 
2287     memcpy(data_buf, cp, data_endptr - cp + 1);
2288     data_endptr -= (cp - data_buf);
2289   }
2290   /* now just copy the string */
2291   strcpy(data_endptr, buf);
2292   data_endptr += strlen(buf);
2293   memset(data_endptr, 0, data_buf + DATABUFSIZ - data_endptr - 1);
2294 }
2295 
2296 #ifdef USE_SCROLLED_TEXT
X_display_refresh(void)2297 void X_display_refresh(void)
2298 {
2299   Arg Args[10];
2300   int n;
2301 
2302   short lines;
2303   char *cp;
2304   XmTextPosition offset, cursor;
2305   Boolean showcur;
2306 
2307   if (toplevel == NULL) return;
2308 
2309   n = 0;
2310   XtSetArg(Args[n], XmNrows, &lines); n++;
2311   XtSetArg(Args[n], XmNtopPosition, &offset); n++;
2312   XtSetArg(Args[n], XmNcursorPosition, &cursor); n++;
2313   XtSetArg(Args[n], XmNautoShowCursorPosition, &showcur); n++;
2314   XtGetValues(frame, Args, n);
2315   printf("Before: %d lines in the display, %ld chars offset %ld cursor (showing %d)\n",
2316 	 (int)lines, (long)offset, (long)cursor, (int)showcur);
2317 
2318   cp = data_endptr;
2319   while (cp > data_buf && lines > 0)
2320     if (*cp-- == '\n') lines--;
2321 
2322 printf("lines = %d, cp = %p, data_buf = %p\n", (int)lines, cp, data_buf);
2323   if (lines == 0) cp++;
2324   if (cp < data_buf) cp = data_buf;
2325 
2326   /* set the editor to display the string */
2327   n = 0;
2328   XtSetArg(Args[n], XmNvalue, data_buf); n++;
2329 #if 0
2330   printf("Setting offset to %d\n", (int)((XmTextPosition)(cp - data_buf)));
2331   XtSetArg(Args[n], XmNtopPosition, (XmTextPosition)(cp - data_buf)); n++;
2332 /*  XtSetArg(Args[n], XmNtopPosition, (XmTextPosition)5); n++; */
2333 #else
2334   XtSetArg(Args[n], XmNautoShowCursorPosition, (XtArgVal)True); n++;
2335   printf("Setting cursor position to %d\n",
2336 	 (int)((XmTextPosition)(data_endptr - data_buf)));
2337   XtSetArg(Args[n], XmNcursorPosition,
2338 	   (XmTextPosition)(data_endptr - data_buf)); n++;
2339 #endif
2340 
2341   XtSetValues(frame, Args, n);
2342 
2343   n = 0;
2344   XtSetArg(Args[n], XmNrows, &lines); n++;
2345   XtSetArg(Args[n], XmNtopPosition, &offset); n++;
2346   XtSetArg(Args[n], XmNcursorPosition, &cursor); n++;
2347   XtGetValues(frame, Args, n);
2348   printf("After: %d lines in the display, %ld chars offset %ld cursor\n",
2349 	 (int)lines, (long)offset, (long)cursor);
2350 }
2351 #else /* not USE_SCROLLED_TEXT */
2352 
X_display_refresh(void)2353 void X_display_refresh(void)
2354 /* very simple code that scrolls the window as required */
2355 {
2356   Arg Args[10];
2357   int n;
2358 
2359   Dimension height;
2360   Position topmargin, botmargin;
2361   XFontStruct *font;
2362   short lines;
2363   char *cp;
2364   int fontheight;
2365 
2366   if (toplevel == NULL) return;
2367 
2368   n = 0;
2369   XtSetArg(Args[n], XtNheight, &height); n++;
2370   XtSetArg(Args[n], XtNtopMargin, &topmargin); n++;
2371   XtSetArg(Args[n], XtNbottomMargin, &botmargin); n++;
2372   XtSetArg(Args[n], XtNfont, &font); n++;
2373   XtGetValues(frame, Args, n);
2374   fontheight = font->max_bounds.ascent + font->max_bounds.descent;
2375   printf("got height = %d, topmargin = %d, botmargin = %d, fontht = %d\n",
2376 	 (int)height, (int)topmargin, (int)botmargin, fontheight);
2377 
2378 
2379   lines = (height - topmargin - botmargin) / fontheight ;
2380 
2381   cp = data_endptr;
2382   while (cp > data_buf && lines > 0)
2383     if (*cp-- == '\n') lines--;
2384 
2385   if (lines == 0) cp++;
2386   if (cp < data_buf) cp = data_buf;
2387 
2388   /* set the editor to display the string */
2389   n = 0;
2390   XtSetArg(Args[n], XtNstring, cp); n++;
2391   XtSetValues(frame, Args, n);
2392 }
2393 
2394 #endif /* not USE_SCROLLED_TEXT */
2395 
2396 
menu_index_by_menu(menu_struct * mp)2397 int menu_index_by_menu(menu_struct *mp)
2398 {
2399   int i;
2400   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
2401     if (MenuArray[i].menu == mp) return(i);
2402 printf("menu_index_by_menu: this should never happen\n");
2403   return(0);
2404 }
2405 
2406 
menu_index_by_widget(Widget w)2407 int menu_index_by_widget(Widget w)
2408 {
2409   int i;
2410   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
2411     if (MenuArray[i].widget == w) return(i);
2412   fprintf(stderr,"menu_index_by_widget: this should never happen\n");
2413   return(0);
2414 }
2415 
find_menu_by_widget(Widget w)2416 menu_struct *find_menu_by_widget(Widget w)
2417 {
2418   int i;
2419   for (i = 0; i < (sizeof(MenuArray)/sizeof(MenuArray[0])); i++)
2420     if (MenuArray[i].widget == w) return(MenuArray[i].menu);
2421   fprintf(stderr,"find_menu_by_widget: this should never happen\n");
2422   return(NULL);
2423 }
2424 
2425 void ActivateMenu(menu_struct *mp);
2426 
MenuCallback(Widget w,caddr_t closure,caddr_t call_data)2427 void MenuCallback(Widget w, caddr_t closure, caddr_t call_data)
2428 {
2429   XawListReturnStruct *cb = (XawListReturnStruct *)call_data;
2430   int i, ItemCount;
2431   menu_struct *menu;
2432 
2433   menu = find_menu_by_widget(w);
2434 
2435   ItemCount = ItemsInMenu(menu);
2436   for (i = 0; i < ItemCount; i++) {
2437     if (!strcmp(cb->string, menu[i].name)) {
2438       /* printf("Trying to run function: %s\n", menu[i].name); */
2439       if (menu[i].submenu != NULL) ActivateMenu(menu[i].submenu);
2440       else (*(menu[i].func))(w, NULL, NULL);
2441       break;
2442     }
2443   }
2444   XawListUnhighlight(w);
2445 }
2446 
MenuDestroyCallback(Widget w,caddr_t closure,caddr_t call_data)2447 void MenuDestroyCallback(Widget w, caddr_t closure, caddr_t call_data)
2448 {
2449   int menunum;
2450 
2451   menunum = menu_index_by_widget(w);
2452   MenuArray[menunum].widget = NULL;
2453 }
2454 
make_menu(menu_struct * menu)2455 Widget make_menu(menu_struct *menu)
2456 /* returns the List widget for the menu, NOT the top shell widget */
2457 {
2458   int n;
2459   Arg Args[20];
2460   Widget top, widget;
2461   String *Items;
2462   int ItemCount;
2463 
2464   top =
2465     XtAppCreateShell(NULL,"menuShell", applicationShellWidgetClass,
2466 		     XtDisplay(toplevel), NULL, 0);
2467 
2468   ItemCount = ItemsInMenu(menu);
2469   Items = (String *)CALLOC(ItemCount + 1, sizeof(String));
2470 
2471   for (n = 0;  n < ItemCount; n++)
2472     Items[n] = XtNewString(menu[n].name);
2473   Items[ItemCount] = NULL;
2474 
2475   n = 0;
2476   XtSetArg(Args[n], XtNdefaultColumns, 1); n++;
2477   XtSetArg(Args[n], XtNforceColumns, True); n++;
2478   XtSetArg(Args[n], XtNlist, Items); n++;
2479   XtSetArg(Args[n], XtNnumberStrings, ItemCount); n++;
2480   widget = XtCreateManagedWidget("menu", listWidgetClass, top, Args, n);
2481   XtAddCallback(widget, XtNcallback, MenuCallback, NULL);
2482   XtAddCallback(widget, XtNdestroyCallback, MenuDestroyCallback, NULL);
2483 /*  XawListChange(widget, Items, ItemCount, 0, True); */
2484 
2485   /* put all menus at a fixed position; this doesn't work for mwm */
2486   n = 0;
2487   XtSetArg(Args[n], XtNx, (XtArgVal)20); n++;
2488   XtSetArg(Args[n], XtNy, (XtArgVal)(30 + 50*menu_index_by_menu(menu))); n++;
2489   XtSetValues(top, Args, n);
2490 
2491   XtRealizeWidget(top);
2492   return(widget);
2493 }
2494 
2495 
RaiseMenu(Widget w)2496 void RaiseMenu(Widget w)
2497 {
2498   /* just bring it up; remember to bring up the SHELL, the list's parent !!! */
2499   XMapRaised(XtDisplay(XtParent(w)), XtWindow(XtParent(w)));
2500 }
2501 
ActivateMenu(menu_struct * mp)2502 void ActivateMenu(menu_struct *mp)
2503 /* if it exists, raise it, otherwise create it */
2504 {
2505   int menunum;
2506   Widget w;
2507 
2508   menunum = menu_index_by_menu(mp);
2509   w = MenuArray[menunum].widget;
2510 
2511   if (w != NULL) RaiseMenu(w);
2512   else MenuArray[menunum].widget = make_menu(mp);
2513 }
2514 
2515 
ActivateTopMenuProc(Widget w,caddr_t closure,caddr_t call_data)2516 void ActivateTopMenuProc(Widget w, caddr_t closure, caddr_t call_data)
2517 /* raise all menus that exist, and create the top-level if required */
2518 {
2519   int i;
2520 
2521   for (i = 0; i < sizeof(MenuArray)/sizeof(MenuArray[0]); i++)
2522     if (MenuArray[i].widget != NULL) RaiseMenu(MenuArray[i].widget);
2523 
2524   /* make sure the main menu is raised in any event */
2525   ActivateMenu(Menu);
2526 }
2527 
2528 
2529 
label_widget(Widget parent,char * string)2530 Widget label_widget(Widget parent, char *string)
2531 {
2532   Arg Args[10];
2533   int n;
2534   Widget w;
2535 
2536   n = 0;
2537   XtSetArg(Args[n], XtNlabel,  (XtArgVal)string); n++;
2538   w = XtCreateManagedWidget("label", labelWidgetClass, parent, Args, n);
2539   return w;
2540 }
2541 
entry_widget(Widget parent,char * string)2542 Widget entry_widget(Widget parent, char *string)
2543 {
2544   Arg Args[10];
2545   int n;
2546   Widget w;
2547 
2548   n = 0;
2549   XtSetArg(Args[n], XtNeditType, XawtextEdit); n++;
2550   w = XtCreateManagedWidget("entry", asciiTextWidgetClass,
2551 			    data_entry, Args, n);
2552   return w;
2553 }
2554 
text_widget(Widget parent,char * string)2555 Widget text_widget(Widget parent, char *string)
2556 {
2557   Arg Args[10];
2558   int n;
2559   Widget w;
2560 
2561   n = 0;
2562   XtSetArg(Args[n], XtNeditType, XawtextRead); n++;
2563   w = XtCreateManagedWidget(string, asciiTextWidgetClass,
2564 			    parent, Args, n);
2565   return w;
2566 }
2567 
make_data_entry_area(Widget parent)2568 void make_data_entry_area(Widget parent)
2569 {
2570   Widget l1, l2, l3, l4;
2571   Arg Args[10];
2572   int n;
2573 
2574   /* put 4 labels in the rowcol widget, and four text editors */
2575   l1 = label_widget(data_entry, "File Name:");
2576 
2577   l2 = label_widget(data_entry, "Cell Name:");
2578   n = 0;
2579   XtSetArg(Args[n], XtNfromVert, l1); n++;
2580   XtSetValues(l2, Args, n);
2581 
2582   l3 = label_widget(data_entry, "Element:");
2583   n = 0;
2584   XtSetArg(Args[n], XtNfromVert, l2); n++;
2585   XtSetValues(l3, Args, n);
2586 
2587   l4 = label_widget(data_entry, "2nd cell/elem:");
2588   n = 0;
2589   XtSetArg(Args[n], XtNfromVert, l3); n++;
2590   XtSetValues(l4, Args, n);
2591 
2592   GlobalFileWidget = entry_widget(data_entry, NULL);
2593   n = 0;
2594   XtSetArg(Args[n], XtNfromHoriz, l1); n++;
2595   XtSetValues(GlobalFileWidget, Args, n);
2596 
2597   GlobalCellWidget = entry_widget(data_entry, NULL);
2598   n = 0;
2599   XtSetArg(Args[n], XtNfromHoriz, l2); n++;
2600   XtSetArg(Args[n], XtNfromVert, GlobalFileWidget); n++;
2601   XtSetValues(GlobalCellWidget, Args, n);
2602 
2603   GlobalDataWidget = entry_widget(data_entry, NULL);
2604   n = 0;
2605   XtSetArg(Args[n], XtNfromHoriz, l3); n++;
2606   XtSetArg(Args[n], XtNfromVert, GlobalCellWidget); n++;
2607   XtSetValues(GlobalDataWidget, Args, n);
2608 
2609   GlobalOtherWidget = entry_widget(data_entry, NULL);
2610   n = 0;
2611   XtSetArg(Args[n], XtNfromHoriz, l4); n++;
2612   XtSetArg(Args[n], XtNfromVert, GlobalDataWidget); n++;
2613   XtSetValues(GlobalOtherWidget, Args, n);
2614 }
2615 
2616 String fallback_resources[] = {
2617     "*input:                  True",
2618     "*Paned*width:            350",
2619     "*label.label:            At least one of each Athena Widget.",
2620     "*Dialog.label:           I am a Dialog widget.",
2621     "*Dialog.value:           Enter new value here.",
2622     "*Dialog*command*label:   ok",
2623     "*Dialog*resizable:       True",
2624     "*Viewport*allowVert:     True",
2625     "*scrollbar*orientation:  horizontal",
2626     "*scrollbar*length:       100",
2627     "*text*height:            75",
2628     "*text*editType:          edit",
2629     "*text*scrollVertical:    whenNeeded",
2630     "*text*scrollHorizonal:   whenNeeded",
2631     NULL,
2632 };
2633 
X_main_loop(int argc,char * argv[])2634 void X_main_loop(int argc, char *argv[])
2635 {
2636   /* toplevel widget is global */
2637   Arg Args[10];
2638   int n;
2639 
2640   /* if we're not using X, just call good old Query(); */
2641   if (getenv("DISPLAY") == NULL) {
2642     Query();
2643     return;
2644   }
2645 
2646   toplevel = XtAppInitialize(&app_con, "Netgen", NULL, 0, &argc, argv,
2647 			     fallback_resources, NULL, 0);
2648 
2649   /* create a vertical pane window to permit children to be resized */
2650   pane = XtCreateManagedWidget("pane", panedWidgetClass, toplevel,NULL, 0);
2651 
2652   /* create a top command and title area */
2653   n = 0;
2654   XtSetArg(Args[n], XtNlabel, (XtArgVal)"Netgen" NETGEN_VERSION "." NETGEN_REVISION);
2655   n++;
2656   title = XtCreateManagedWidget("title", commandWidgetClass, pane, Args, n);
2657   XtAddCallback(title, XtNcallback, ActivateTopMenuProc, NULL);
2658 
2659   /* create a data entry area for the four text fields */
2660 /*
2661   n = 0;
2662   data_entry = XtCreateManagedWidget("rowcol", boxWidgetClass, pane, Args, n);
2663 */
2664   n = 0;
2665   data_entry = XtCreateManagedWidget("rowcol", formWidgetClass, pane, Args, n);
2666 
2667   make_data_entry_area(data_entry);
2668 
2669   /* create two text widgets */
2670   cells_frame = text_widget(pane, "cells");
2671   frame = text_widget(pane, "text");
2672 
2673   XtRealizeWidget(toplevel);
2674   XtAppMainLoop(app_con);
2675 }
2676 #endif /* X11_ATHENA_WIDGETS */
2677 
2678 #endif  /* HAVE_X11 */
2679 
2680