~ubuntu-branches/ubuntu/precise/xcircuit/precise

« back to all changes in this revision

Viewing changes to schema.c

  • Committer: Bazaar Package Importer
  • Author(s): David Z Maze
  • Date: 2003-08-24 09:08:10 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20030824090810-5d6ptk9msqsbsnqv
Tags: 3.1.19-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <stdio.h>
11
11
#include <stdlib.h>
12
12
#include <string.h>
13
 
#if defined(DARWIN)
14
 
#include <sys/malloc.h>
15
 
#else
16
 
#include <malloc.h>
17
 
#endif
18
13
 
19
14
#include <X11/Intrinsic.h>
20
15
#include <X11/StringDefs.h>
 
16
 
 
17
#ifdef TCL_WRAPPER 
 
18
#include <tk.h>
 
19
#else
21
20
#include "Xw/Xw.h"
22
21
#include "Xw/MenuBtn.h"
 
22
#endif
23
23
 
24
24
/*-------------------------------------------------------------------------*/
25
25
/* Local includes                                                          */
38
38
/* External Variable definitions                                          */
39
39
/*------------------------------------------------------------------------*/
40
40
 
 
41
#ifdef TCL_WRAPPER
 
42
extern Tcl_Interp *xcinterp;
 
43
#endif
 
44
 
41
45
extern Globaldata xobjs;
42
46
extern Clientdata areastruct;
43
47
extern short      eventmode;
44
48
extern int        *appcolors;
45
 
extern Widget     menuwidgets[];
46
 
extern Widget     netbutton;
47
 
extern objectpair *pushlist;
 
49
extern xcWidget     menuwidgets[];
 
50
extern xcWidget   netbutton;
48
51
extern char       _STR[150];
49
52
extern char       _STR2[250];
50
53
 
51
54
/*-------------------------------------------------------------------------*/
52
55
#ifdef SCHEMA
53
56
 
54
 
extern Widget wsymb, wschema;
 
57
extern xcWidget wsymb, wschema;
55
58
 
56
59
/*--------------------------------------------------------*/
57
60
/* Menu calls (procedure wrappers)                        */
58
61
/*--------------------------------------------------------*/
59
62
 
60
 
void callgennet(Widget w, u_int mode, caddr_t calldata)
 
63
void callgennet(xcWidget w, pointertype mode, caddr_t calldata)
61
64
{
62
65
   switch(mode) {
63
66
     case 0:
67
70
        gennet("sim", "sim");
68
71
        break;
69
72
     case 2:
70
 
        gennet("pcb", "pcb");
 
73
        gennet("pcb", "pcbnet");
71
74
        break;
72
75
     case 3:
73
76
        gennet("flatspice", "fspc");
78
81
   }
79
82
}
80
83
 
81
 
/*------------------------------------------------------------*/
82
 
/* Enable schematic capture (set schemon and realize widgets) */
83
 
/*------------------------------------------------------------*/
 
84
/*--------------------------------------------------------------*/
 
85
/* Enable schematic capture (set schemon and realize widgets)   */
 
86
/* If mode == 1, do a redraw (e.g., not called during a file    */
 
87
/* load)                                                        */
 
88
/*--------------------------------------------------------------*/
84
89
 
85
 
void doxschema(Widget w, caddr_t clientdata, caddr_t calldata)
 
90
void doxschema(xcWidget w, pointertype mode, caddr_t calldata)
86
91
{
87
92
   Arg wargs[1];
88
93
 
89
94
   if (areastruct.schemon) {
90
95
      areastruct.schemon = False;
 
96
#ifndef TCL_WRAPPER
91
97
      XtUnmanageChild(wschema);
92
98
      XtUnmanageChild(wsymb);
93
99
      XtUnmanageChild(netbutton);
94
100
 
95
101
      XtSetArg(wargs[0], XtNlabel, "Enable XSchema");
96
102
      XtSetValues(OptionsEnableXSchemaButton, wargs, 1);
 
103
#endif
97
104
   }
98
105
   else {
99
106
      areastruct.schemon = True;
 
107
#ifndef TCL_WRAPPER
100
108
      XtManageChild(wschema);
101
109
      XtManageChild(wsymb);
102
110
      XtManageChild(netbutton);
103
111
 
104
112
      XtSetArg(wargs[0], XtNlabel, "Disable XSchema");
105
113
      XtSetValues(OptionsEnableXSchemaButton, wargs, 1);
 
114
#endif
106
115
   }
107
116
 
108
117
   /* Redraw the screen, since this action may effect the presence of   */
109
118
   /* pins and schematic informational labels.                          */
110
119
 
111
 
   drawarea(NULL, NULL, NULL);
 
120
   if (mode) drawarea(NULL, NULL, NULL);
112
121
}
113
122
 
114
123
/*------------------------------------------------------------------------*/
132
141
 
133
142
   /* Find the page number of this page object */
134
143
   for (p = 0; p < xobjs.pages; p++) {
135
 
      if (xobjs.pagelist[p]->pageobj != NULL) {
136
 
         if (xobjs.pagelist[p]->pageobj == thispageobj) {
 
144
      if (xobjs.pagelist[p]->pageinst != NULL) {
 
145
         if (xobjs.pagelist[p]->pageinst->thisobject == thispageobj) {
137
146
            thispage = p;
138
147
            break;
139
148
         }
140
149
      }
141
150
   }
142
151
   if (p == xobjs.pages) {
143
 
      fprintf(stderr, "Error:  Object is not a page object!\n");
 
152
      Fprintf(stderr, "Error:  Object is not a page object!\n");
144
153
      return 0;
145
154
   }
146
155
 
149
158
      changed = False;
150
159
      for (p = 0; p < xobjs.pages; p++) {
151
160
         if (p == thispage) continue;
152
 
         if (xobjs.pagelist[p]->pageobj != NULL) {
153
 
            if (!strcmp(xobjs.pagelist[p]->pageobj->name, thispageobj->name)) {
 
161
         if (xobjs.pagelist[p]->pageinst != NULL) {
 
162
            if (!strcmp(xobjs.pagelist[p]->pageinst->thisobject->name,
 
163
                        thispageobj->name)) {
154
164
               /* append ":2" to name or update suffix to ensure uniqueness */
155
165
               if (clnptr == NULL)
156
166
                  sprintf(thispageobj->name, "%s:2", thispageobj->name);
174
184
/* Find connectivity of a selection     */
175
185
/*--------------------------------------*/
176
186
 
177
 
void startconnect(Widget button, caddr_t clientdata, caddr_t calldata)
 
187
void startconnect(xcWidget button, caddr_t clientdata, caddr_t calldata)
178
188
{
179
189
   if (areastruct.selects > 0)
180
190
      connectivity(button, clientdata, calldata);
185
195
}
186
196
 
187
197
/*----------------------------------------------------------------------*/
188
 
/* rconnectivity():  Find electrical connections into a node.           */
 
198
/* connectivity():  Find electrical connections into a node.            */
189
199
/* (does recursive search on object heirarchy)                          */
 
200
/* Returns net number found (0 if no network found, -1 if error)        */
190
201
/*----------------------------------------------------------------------*/
191
202
 
192
 
void connectivity(Widget button, caddr_t clientdata, caddr_t calldata)
 
203
int connectivity(xcWidget button, caddr_t clientdata, caddr_t calldata)
193
204
{
194
205
   short *gsel;
195
206
   genericptr ggen;
196
 
   int depth, netid;
197
 
   objectpair *seltop, *nextptr;
 
207
   int depth, netid = -1;
 
208
   pushlistptr seltop, nextptr;
198
209
   objectptr nettop, thisobj;
199
210
   char *snew;
200
211
   stringpart *ppin;
201
212
 
202
 
   seltop = (objectpair *)malloc(sizeof(objectpair));
203
 
   seltop->thisobject = objectdata;
204
 
   seltop->thisinst = NULL;
205
 
   seltop->nextpair = NULL;
 
213
   /* erase any existing highlighted network */
 
214
   highlightnet(topobject, areastruct.topinstance, -1, 0);
 
215
 
 
216
   seltop = (pushlistptr)malloc(sizeof(pushlist));
 
217
   seltop->thisinst = areastruct.topinstance;
 
218
   seltop->next = NULL;
206
219
 
207
220
   /* pick the first selection that looks like a valid network part */
208
221
 
209
222
   if (areastruct.selects > 0) {
210
223
      for (gsel = areastruct.selectlist; gsel < areastruct.selectlist +
211
224
                areastruct.selects; gsel++) {
212
 
         ggen = *(objectdata->plist + *gsel);
 
225
         ggen = *(topobject->plist + *gsel);
213
226
         if (SELECTTYPE(gsel) == LABEL) {
214
227
            labelptr glab = SELTOLABEL(gsel);
215
228
            if (glab->pin == LOCAL || glab->pin == GLOBAL) break;
232
245
   /* entire matrix stack.                                      */
233
246
 
234
247
   if (ggen != NULL) {
235
 
      if (checkvalid(objectdata) == -1) {
 
248
      if (checkvalid(topobject) == -1) {
236
249
         destroynets();
237
250
         createnets();
238
251
      }
239
252
      if ((netid = is_resolved(&ggen, seltop, &nettop)) != 0) {
240
 
         /* printf("Net ID is %d in object %s\n", netid, nettop->name); */
 
253
         /* Fprintf(stdout, "Net ID is %d in object %s\n", netid, nettop->name); */
241
254
         depth = pushnetwork(seltop, nettop);
242
 
         /* printf(">> Pushed network %d levels deep\n", depth); */
 
255
         /* Fprintf(stdout, ">> Pushed network %d levels deep\n", depth); */
243
256
         nextptr = seltop;
244
 
         while (nextptr->thisobject != nettop)
245
 
            nextptr = nextptr->nextpair;
246
 
         highlightnet(nettop, nextptr->thisinst, netid);
 
257
         while (nextptr->thisinst->thisobject != nettop)
 
258
            nextptr = nextptr->next;
 
259
 
 
260
         nextptr->thisinst->thisobject->highlight.netid = netid;
 
261
         nextptr->thisinst->thisobject->highlight.thisinst = nextptr->thisinst;
 
262
            
 
263
         highlightnet(nettop, nextptr->thisinst, netid, 1);
247
264
 
248
265
         /* pop the matrix stack */
249
266
         while (depth-- > 0) 
252
269
         /* print the net name to the message window */
253
270
 
254
271
         ppin = nettopin(netid, nettop, NULL);
255
 
         snew = textprint(ppin, NORMINST);
 
272
         snew = textprint(ppin, areastruct.topinstance);
 
273
 
256
274
         sprintf(_STR, "Network is \"%s\" in %s", snew, nettop->name);
257
275
         Wprintf(_STR);
 
276
 
 
277
#ifdef TCL_WRAPPER
 
278
         Tcl_SetObjResult(xcinterp, Tcl_NewStringObj(snew, strlen(snew)));
 
279
#endif
258
280
         free(snew);
259
281
      }
260
282
      else
261
283
         Wprintf("Selected element is not part of a valid network.");
262
284
   }
263
 
   else 
 
285
   else { 
264
286
      Wprintf("No networks found near the cursor position");
 
287
      netid = 0;
 
288
   }
265
289
 
266
290
   /* free up linked list */
267
291
 
268
292
   while (seltop != NULL) {
269
 
      nextptr = seltop->nextpair;
 
293
      nextptr = seltop->next;
270
294
      free(seltop);
271
295
      seltop = nextptr;
272
296
   }
 
297
   return netid;
273
298
}
274
299
 
275
300
/*--------------------------------------------------------------*/
287
312
 
288
313
   /* Apply only to schematic objects */
289
314
 
290
 
   if (cschem->schemtype != SCHEMATIC && cschem->symschem == NULL) {
291
 
      if (cschem->schemtype == FUNDAMENTAL) cschem->schemtype = SYMBOL;
292
 
      for (cgen = cschem->plist; cgen < cschem->plist + cschem->parts; cgen++) {
293
 
         if ((*cgen)->type == LABEL) {
294
 
            clab = TOLABEL(cgen);
295
 
            if (clab->pin == INFO) {
296
 
               cschem->schemtype = FUNDAMENTAL;
297
 
               break;
 
315
   if (cschem->schemtype != SCHEMATIC) {
 
316
      if (cschem->schemtype == FUNDAMENTAL)
 
317
         cschem->schemtype = SYMBOL;
 
318
      if (cschem->symschem == NULL) {
 
319
         for (cgen = cschem->plist; cgen < cschem->plist + cschem->parts; cgen++) {
 
320
            if ((*cgen)->type == LABEL) {
 
321
               clab = TOLABEL(cgen);
 
322
               if (clab->pin == INFO) {
 
323
                  cschem->schemtype = FUNDAMENTAL;
 
324
                  break;
 
325
               }
298
326
            }
299
327
         }
300
328
      }
312
340
/* Pin conversion subroutine for dopintype()            */
313
341
/*------------------------------------------------------*/
314
342
 
315
 
void pinconvert(labelptr thislab, u_int mode)
 
343
void pinconvert(labelptr thislab, pointertype mode)
316
344
{
317
345
   thislab->pin = mode;
318
346
   switch (mode) {
320
348
         thislab->color = DEFAULTCOLOR;         /* nominally black */
321
349
         break;
322
350
      case GLOBAL:
323
 
         thislab->color = BBOXCOLOR;            /* orange */
 
351
         thislab->color = GLOBALPINCOLOR;       /* orange */
324
352
         break;
325
353
      case LOCAL:
326
 
         thislab->color = SNAPCOLOR;            /* red */
 
354
         thislab->color = LOCALPINCOLOR;        /* red */
327
355
         break;
328
356
      case INFO:
329
 
         thislab->color = AUXCOLOR;             /* green */
 
357
         thislab->color = INFOLABELCOLOR;       /* green */
330
358
         break;
331
359
   }
332
360
}
335
363
/* Change a label's type to NORMAL, GLOBAL, INFO, or LOCAL */
336
364
/*---------------------------------------------------------*/
337
365
 
338
 
void dopintype(Widget w, u_int mode, caddr_t calldata)
 
366
void dopintype(xcWidget w, pointertype mode, caddr_t calldata)
339
367
{
340
368
   short *gsel;
341
369
   char typestr[40];
368
396
         labelptr glab = SELTOLABEL(gsel);
369
397
         savetype = glab->pin;
370
398
         pinconvert(glab, mode);
371
 
         setobjecttype(objectdata);
 
399
         setobjecttype(topobject);
372
400
      }
373
401
 
374
402
   if (savetype >= 0) {
385
413
/* Set colors on the symbol/schematic buttons appropriately */
386
414
/*----------------------------------------------------------*/
387
415
 
 
416
#ifdef TCL_WRAPPER
 
417
 
 
418
void setsymschem()
 
419
{
 
420
   /* This is temporary (hopefully). . . Call the Tcl function  */
 
421
   /* "setsymschem" which had better be defined by the wrapper. */
 
422
 
 
423
   Tcl_SavedResult state;
 
424
 
 
425
   Tcl_SaveResult(xcinterp, &state);
 
426
   Tcl_Eval(xcinterp, "xcircuit::setsymschem");
 
427
   Tcl_RestoreResult(xcinterp, &state);
 
428
}
 
429
 
 
430
#else
 
431
 
388
432
void setsymschem()
389
433
{
390
434
   Arg aargs[2], bargs[2];
391
435
 
392
436
   /* Set menu items appropriately for this object */
393
437
 
394
 
   if (objectdata->symschem != NULL) {
395
 
      if (objectdata->schemtype == SCHEMATIC) {
 
438
   if (topobject->symschem != NULL) {
 
439
      if (topobject->schemtype == SCHEMATIC) {
396
440
         XtSetArg(aargs[0], XtNlabel, "Go To Symbol");
397
441
         XtSetArg(bargs[0], XtNlabel, "Disassociate Symbol");
398
442
      }
402
446
      }
403
447
   }
404
448
   else {
405
 
      if (objectdata->schemtype == SCHEMATIC) {
 
449
      if (topobject->schemtype == SCHEMATIC) {
406
450
         XtSetArg(aargs[0], XtNlabel, "Make Matching Symbol");
407
451
         XtSetArg(bargs[0], XtNlabel, "Associate with Symbol");
408
452
      }
416
460
 
417
461
   /* Set colors on the symbol and schematic buttons */
418
462
 
419
 
   if (objectdata->schemtype == SCHEMATIC) {
420
 
      if (objectdata->symschem == NULL) {
 
463
   if (topobject->schemtype == SCHEMATIC) {
 
464
      if (topobject->symschem == NULL) {
421
465
         XtSetArg(aargs[0], XtNbackground, OFFBUTTONCOLOR);
422
466
         XtSetArg(aargs[1], XtNforeground, OFFBUTTONCOLOR);
423
467
      }
430
474
      XtSetArg(bargs[0], XtNbackground, SNAPCOLOR);
431
475
   }
432
476
   else {
433
 
      if (objectdata->symschem != NULL) {
 
477
      if (topobject->symschem != NULL) {
434
478
         XtSetArg(bargs[0], XtNbackground, BACKGROUND);
435
479
         XtSetArg(bargs[1], XtNforeground, FOREGROUND);
436
480
      }
440
484
      }
441
485
 
442
486
      XtSetArg(aargs[1], XtNforeground, FOREGROUND);
443
 
      if (objectdata->schemtype == FUNDAMENTAL)
 
487
      if (topobject->schemtype == FUNDAMENTAL)
444
488
         XtSetArg(aargs[0], XtNbackground, AUXCOLOR);
445
 
      else if (objectdata->schemtype == TRIVIAL || objectdata->symschem != NULL)
 
489
      else if (topobject->schemtype == TRIVIAL || topobject->symschem != NULL)
446
490
         XtSetArg(aargs[0], XtNbackground, SNAPCOLOR);
447
491
      else {
448
492
         XtSetArg(aargs[0], XtNbackground, OFFBUTTONCOLOR);
456
500
   XtSetValues(wschema, bargs, 2);
457
501
}
458
502
 
 
503
#endif
 
504
 
459
505
/*--------------------------------------------------------*/
460
506
/* Find the page number for an object                     */
461
507
/*--------------------------------------------------------*/
464
510
{
465
511
   int tpage;
466
512
 
467
 
   for (tpage = 0; tpage < xobjs.pages; tpage++) {
468
 
      if (xobjs.pagelist[tpage]->pageobj == pobj) return tpage;
469
 
   }
 
513
   for (tpage = 0; tpage < xobjs.pages; tpage++)
 
514
      if (xobjs.pagelist[tpage]->pageinst != NULL)
 
515
         if (xobjs.pagelist[tpage]->pageinst->thisobject == pobj)
 
516
            return tpage;
 
517
 
470
518
   return -1;
471
519
}
472
520
 
473
 
/*-------------------------------------------------------*/
474
 
/* Recursively find all sub-circuits associated with the */
475
 
/* top-level circuit and set their filenames to be the   */
476
 
/* same.                                                 */
477
 
/*                                                       */
478
 
/* Avoid possible recursion problems by limiting the     */
479
 
/* number of recursion levels.  Presumably no circuit    */
480
 
/* would have more than several hundred hierarchical     */
481
 
/* levels.                                               */
482
 
/*-------------------------------------------------------*/
 
521
/*------------------------------------------------------*/
 
522
/* Enumerate all of the pages which are subschematics   */
 
523
/* of "toppage" and return the result in the list       */
 
524
/* passed as a pointer.  The list is assumed to be      */
 
525
/* already allocated, and equal to the total number of  */
 
526
/* pages (xobjs.pages).                                 */
 
527
/*                                                      */
 
528
/* Avoid possible recursion problems by limiting the    */
 
529
/* number of recursion levels.  Presumably no circuit   */
 
530
/* would have more than several hundred hierarchical    */
 
531
/* levels.                                              */
 
532
/*------------------------------------------------------*/
483
533
 
484
 
int findsubschems(int toppage, objectptr cschem, int level)
 
534
int findsubschems(int toppage, objectptr cschem, int level, short *pagelist)
485
535
{
486
536
   genericptr *cgen;
487
537
 
488
 
   if (level == HIERARCHY_LIMIT) return -1;
 
538
   if (level == HIERARCHY_LIMIT) return -1;     /* sanity check */
489
539
 
490
540
   for (cgen = cschem->plist; cgen < cschem->plist + cschem->parts; cgen++) {
491
541
      if ((*cgen)->type == OBJECT) {
493
543
 
494
544
         if (cobj->symschem != NULL) {
495
545
            int pageno = findpageobj(cobj->symschem);
496
 
            /* printf("Symbol %s has schematic at page %d\n", cobj->name, pageno); */
497
 
            if (pageno < 0) {   /* This shouldn't happen (hopefully) */
498
 
               Wprintf("Error: disconnected schematic!\n");
499
 
            }
500
 
            else {
501
 
               if (xobjs.pagelist[pageno]->filename != NULL)
502
 
                  free(xobjs.pagelist[pageno]->filename);
503
 
               xobjs.pagelist[pageno]->filename =
504
 
                        strdup(xobjs.pagelist[toppage]->filename);
505
 
            }
 
546
            if ((pageno >= 0) && (pageno < xobjs.pages))
 
547
                pagelist[pageno]++;
506
548
 
507
549
            /* A symbol on its own schematic page is allowed for clarity */
508
550
            /* of the schematic, but this cannot be a functional part of */
509
551
            /* the schematic circuit!                                    */
510
552
            
511
553
            if (cobj->symschem != cschem) {
512
 
               /* printf("Searching for dependencies of symbol %s\n", cobj->name); */
513
 
               if (findsubschems(toppage, cobj->symschem, level + 1) == -1)
 
554
               if (findsubschems(toppage, cobj->symschem,
 
555
                                level + 1, pagelist) == -1)
514
556
                  return -1;
515
557
            }
516
558
         }
517
559
         else if (cobj->schemtype != FUNDAMENTAL && cobj->schemtype != TRIVIAL) {
518
560
            /* Check symbols acting as their own schematics */
519
 
            if (findsubschems(toppage, cobj, level + 1) == -1)
 
561
            if (findsubschems(toppage, cobj, level + 1, pagelist) == -1)
520
562
               return -1;
521
563
         }
522
564
      }
524
566
   return 0;
525
567
}
526
568
 
 
569
/*-------------------------------------------------------*/
 
570
/* Recursively find all sub-circuits associated with the */
 
571
/* top-level circuit and set their filenames to be the   */
 
572
/* same.                                                 */
 
573
/*-------------------------------------------------------*/
 
574
 
 
575
void collectsubschems(int toppage)
 
576
{
 
577
   int level = 0;
 
578
   objectptr cschem;
 
579
   short *pagelist, pageno;
 
580
 
 
581
   if (xobjs.pagelist[toppage]->pageinst == NULL) return;
 
582
 
 
583
   cschem = xobjs.pagelist[toppage]->pageinst->thisobject;
 
584
 
 
585
   pagelist = (short *)malloc(xobjs.pages * sizeof(short));
 
586
 
 
587
   for (pageno = 0; pageno < xobjs.pages; pageno++)
 
588
      pagelist[pageno] = 0;
 
589
 
 
590
   findsubschems(toppage, cschem, 0, pagelist);
 
591
 
 
592
   for (pageno = 0; pageno < xobjs.pages; pageno++) {
 
593
      if (pagelist[pageno] > 0) {
 
594
          if (xobjs.pagelist[pageno]->filename != NULL)
 
595
             free(xobjs.pagelist[pageno]->filename);
 
596
          xobjs.pagelist[pageno]->filename =
 
597
             strdup(xobjs.pagelist[toppage]->filename);
 
598
      }
 
599
   } 
 
600
   free((char *)pagelist);
 
601
}
 
602
 
527
603
/*--------------------------------------------------------*/
528
604
/* Copy label to corresponding schematic/symbol           */
529
605
/*--------------------------------------------------------*/
532
608
{
533
609
   labelptr *newlabel, tlabel;
534
610
   genericptr *tgen;
535
 
   objectptr schemobj = objectdata->symschem;
 
611
   objectptr schemobj = topobject->symschem;
536
612
 
537
613
   if (areastruct.schemon && schemobj != NULL && (pinlab->pin == LOCAL)) {
538
614
 
558
634
 
559
635
      /* place label just outside bounding box, then recompute bbox */
560
636
 
561
 
      (*newlabel)->position.x = schemobj->lowerleft.x + (schemobj->width >> 1);
562
 
      (*newlabel)->position.y = schemobj->lowerleft.y - TEXTHEIGHT
 
637
      (*newlabel)->position.x = schemobj->bbox.lowerleft.x + (schemobj->bbox.width >> 1);
 
638
      (*newlabel)->position.y = schemobj->bbox.lowerleft.y - TEXTHEIGHT
563
639
           * (*newlabel)->scale;
564
640
      schemobj->parts++;
565
641
      incr_changes(schemobj);
566
642
      schemobj->valid = False;
567
 
      singlebbox(objectdata, ENDPART);
 
643
      singlebbox(ENDPART);
568
644
   }
569
645
}
570
646
 
614
690
   if (areastruct.schemon == False || symobj->symschem != NULL) return 0;
615
691
 
616
692
   for (cpage = 0; cpage < xobjs.pages; cpage++) {
617
 
      checkpage = xobjs.pagelist[cpage]->pageobj;
618
 
      if (checkpage != NULL) {
 
693
      if (xobjs.pagelist[cpage]->pageinst != NULL) {
 
694
         checkpage = xobjs.pagelist[cpage]->pageinst->thisobject;
619
695
         if (!strcmp(checkpage->name, cname)) {
620
696
            symobj->symschem = checkpage;
621
697
            symobj->schemtype = SYMBOL;
636
712
 
637
713
void changeotherpins(labelptr newlabel, stringpart *oldstring)
638
714
{
639
 
   objectptr other = objectdata->symschem;
 
715
   objectptr other = topobject->symschem;
640
716
   genericptr *tgen;
641
717
   labelptr tlab;
642
718
 
663
739
/*  there is no corresponding schematic/symbol, nothing happens.        */
664
740
/*----------------------------------------------------------------------*/
665
741
 
666
 
void swapschem(Widget w, u_int mode, caddr_t calldata)
 
742
void swapschem(xcWidget w, pointertype mode, caddr_t calldata)
667
743
{
668
 
   objectptr savepage = objectdata;
 
744
   objectptr savepage = topobject;
669
745
   labelptr  *pinlab;
670
746
   genericptr *plab;
671
747
   Boolean lflag;
 
748
   pushlistptr stacktop;
672
749
 
673
750
   if (areastruct.schemon == False) return;
674
751
 
677
754
 
678
755
   /* Create symbol or schematic, if allowed by mode */
679
756
 
680
 
   if ((objectdata->symschem == NULL) && (mode != 0)) {
681
 
      if (objectdata->schemtype != SCHEMATIC) {
 
757
   if ((topobject->symschem == NULL) && (mode != 0)) {
 
758
      if (topobject->schemtype != SCHEMATIC) {
682
759
         int tpage;
683
760
 
684
761
         /* create a new page for the new schematic */
685
762
 
686
763
         for (tpage = 0; tpage < xobjs.pages; tpage++)
687
 
            if (xobjs.pagelist[tpage]->pageobj == NULL) break;
 
764
            if (xobjs.pagelist[tpage]->pageinst == NULL) break;
 
765
 
 
766
         /* Push the current instance onto the push stack */
 
767
         /* Change the page without destroying the pushlist */
 
768
 
 
769
         push_stack(&areastruct.stack, areastruct.topinstance);
 
770
         stacktop = areastruct.stack;
 
771
         areastruct.stack = NULL;
688
772
         changepage(tpage);
 
773
         areastruct.stack = stacktop;
689
774
      }
690
775
      else {
691
776
         objectptr *newobject;
703
788
         (*newobject)->schemtype = SYMBOL;
704
789
         (*newobject)->hidden = False;
705
790
         (*newobject)->devname = NULL;
706
 
         objectdata = *newobject;
 
791
 
 
792
         incr_changes(*newobject);
 
793
 
 
794
         /* Generate a library instance for this object and set the */
 
795
         /* top instance to point to it.                            */
 
796
 
 
797
         push_stack(&areastruct.stack, areastruct.topinstance);
 
798
         areastruct.topinstance = addtoinstlist(libnum, *newobject, FALSE);
707
799
 
708
800
         /* Generate the default bounding box for a size-zero object */
709
 
         calcbbox(*newobject);
 
801
         calcbbox(areastruct.topinstance);
710
802
      }
711
803
 
712
804
      /* set links between the two objects */
713
805
 
714
 
      savepage->symschem = objectdata;
715
 
      objectdata->symschem = savepage;
 
806
      savepage->symschem = topobject;
 
807
      topobject->symschem = savepage;
716
808
 
717
809
      /* make the name of the new object equal to that of the old */
718
810
 
719
 
      strcpy(objectdata->name, savepage->name);
 
811
      strcpy(topobject->name, savepage->name);
720
812
 
721
813
      /* copy all pin labels into the new object */
722
814
 
731
823
               /* Only make one copy of each pin name */
732
824
 
733
825
               lflag = False;
734
 
               for (tgen = objectdata->plist; tgen <
735
 
                        objectdata->plist + objectdata->parts; tgen++) {
 
826
               for (tgen = topobject->plist; tgen <
 
827
                        topobject->plist + topobject->parts; tgen++) {
736
828
                  if ((*tgen)->type == LABEL) {
737
829
                     tlab = TOLABEL(tgen);
738
830
                     if (!stringcomp(tlab->string, lpin->string)) lflag = True;
740
832
               }
741
833
               if (lflag == True) continue;
742
834
 
743
 
               NEW_LABEL(pinlab, objectdata);
 
835
               NEW_LABEL(pinlab, topobject);
744
836
               (*pinlab)->pin = lpin->pin;
745
837
               (*pinlab)->color = lpin->color;
746
838
               (*pinlab)->rotation = 0;
747
839
               (*pinlab)->scale = 1.0;
748
840
               (*pinlab)->justify = areastruct.justify; 
749
841
               (*pinlab)->position.x = 0;
750
 
               (*pinlab)->position.y = objectdata->parts * (TEXTHEIGHT + 10);
 
842
               (*pinlab)->position.y = topobject->parts * (TEXTHEIGHT + 10);
751
843
               (*pinlab)->num_params = 0;
752
844
               (*pinlab)->passed = NULL;
753
845
               u2u_snap(&((*pinlab)->position));
754
846
               (*pinlab)->string = stringcopy(lpin->string);
755
 
               objectdata->parts++;
756
 
               incr_changes(objectdata);
 
847
               topobject->parts++;
 
848
               incr_changes(topobject);
757
849
            }
758
850
         }
759
 
         calcbbox(objectdata);
760
851
      }
 
852
      calcbbox(areastruct.topinstance);
761
853
 
762
854
      /* Recreate the user library with the new symbol */
763
855
      if (savepage->schemtype != SYMBOL) composelib(USERLIB);
764
856
   }
765
 
   else if (objectdata->symschem != NULL) {
766
 
      objectdata = objectdata->symschem;
 
857
   else if (topobject->symschem != NULL) {
 
858
 
 
859
      /* If symschem matches the last entry on the push stack, then we  */
 
860
      /* pop; otherwise, we push.                                       */
 
861
 
 
862
      if (areastruct.stack && areastruct.stack->thisinst->thisobject == topobject->symschem) {
 
863
         areastruct.topinstance = areastruct.stack->thisinst;
 
864
         pop_stack(&areastruct.stack);
 
865
      }
 
866
      else {
 
867
         int p;
 
868
         objinstptr syminst = NULL;
 
869
         liblistptr symlist;
 
870
 
 
871
         /* If symschem is a schematic, find the appropriate page */
 
872
 
 
873
         for (p = 0; p < xobjs.pages; p++) {
 
874
            syminst = xobjs.pagelist[p]->pageinst;
 
875
            if (syminst != NULL)
 
876
               if (syminst->thisobject == topobject->symschem)
 
877
                  break;
 
878
         }
 
879
         if (p == xobjs.pages) {
 
880
 
 
881
            /* If symschem is a symbol, and it wasn't on the push stack, */
 
882
            /* get the library default symbol and go there.              */
 
883
 
 
884
            for (p = 0; p < xobjs.numlibs; p++) {
 
885
               for (symlist = xobjs.userlibs[p].instlist; symlist != NULL;
 
886
                        symlist = symlist->next) {
 
887
                  syminst = symlist->thisinst;
 
888
                  if (syminst->thisobject == topobject->symschem &&
 
889
                        symlist->virtual == FALSE)
 
890
                     break;
 
891
               }
 
892
               if (symlist != NULL) break;
 
893
            }
 
894
            if (p == xobjs.numlibs) {
 
895
               Fprintf(stderr, "swapschem(): BAD SYMSCHEM\n");
 
896
               return;
 
897
            }
 
898
         }
 
899
               
 
900
         push_stack(&areastruct.stack, areastruct.topinstance);
 
901
         areastruct.topinstance = syminst;
 
902
      }
767
903
   }
768
904
 
769
 
   if (areastruct.selects > 0) free(areastruct.selectlist);
770
 
   areastruct.selects = 0;
771
 
 
772
 
   setpage();
 
905
   /* If there was no action, then there is nothing more to do. */
 
906
 
 
907
   if (topobject == savepage) return;
 
908
 
 
909
   setpage(TRUE);
773
910
   transferselects();
774
911
   refresh(NULL, NULL, NULL);
775
 
 
776
912
   setsymschem();
777
913
}
778
914
 
780
916
/* Wrapper for swapschem() when generating a new symbol.                */
781
917
/*----------------------------------------------------------------------*/
782
918
 
783
 
void makesymbol(Widget w, caddr_t calldata)
 
919
void makesymbol(xcWidget w, caddr_t calldata)
784
920
{
785
921
   /* copy name from popup prompt buffer and check */
786
922
 
787
 
   strcpy(objectdata->name, _STR2);
788
 
   checkname(objectdata);
789
 
   swapschem(w, (u_int)1, calldata);
 
923
   strcpy(topobject->name, _STR2);
 
924
   checkname(topobject);
 
925
   swapschem(w, (pointertype)1, calldata);
790
926
}
791
927
 
792
928
/*----------------------------------------------------------------------*/
794
930
/* for the object name, as you would when doing selectsave().           */ 
795
931
/*----------------------------------------------------------------------*/
796
932
 
797
 
void dobeforeswap(Widget w, caddr_t clientdata, caddr_t calldata)
 
933
void dobeforeswap(xcWidget w, caddr_t clientdata, caddr_t calldata)
798
934
{
799
935
   buttonsave *popdata = (buttonsave *)malloc(sizeof(buttonsave));
800
936
 
804
940
 
805
941
   /* Check for requirement to change the name before creating the symbol */
806
942
 
807
 
   if ((objectdata->symschem == NULL) && (objectdata->schemtype == SCHEMATIC)
808
 
                && (strstr(objectdata->name, "Page ") != NULL)) {
 
943
   if ((topobject->symschem == NULL) && (topobject->schemtype == SCHEMATIC)
 
944
                && (strstr(topobject->name, "Page ") != NULL)) {
809
945
 
810
946
      /* Get a name for the new object */
811
947
 
815
951
      popupprompt(w, "Enter name for new object:", "\0", makesymbol, popdata, NULL);
816
952
   }
817
953
   else
818
 
      swapschem(w, (u_int)1, calldata);
 
954
      swapschem(w, (pointertype)1, calldata);
819
955
}
820
956
 
821
957
/*------------------------------------------*/
828
964
      Wprintf("Cannot disassociate schematics in this mode");
829
965
   }
830
966
   else {
831
 
      objectdata->symschem->symschem = NULL;
832
 
      objectdata->symschem = NULL;
 
967
      topobject->symschem->symschem = NULL;
 
968
      topobject->symschem = NULL;
833
969
      setsymschem();
834
970
      Wprintf("Schematic and symbol are now unlinked.");
835
971
   }
836
972
}
837
973
 
838
974
/*--------------------------------------------------------------*/
839
 
/* Schematic<-->symbol association.  Determine action from      */
840
 
/* context (associate/disassociate, symbol or schematic)        */
 
975
/* Schematic<-->symbol association.  Determine whether action   */
 
976
/* acts on a symbol or a schematic from context.                */
 
977
/* mode == 0 associate only.                                    */
 
978
/* mode == 1 determine action (associate or disassociate) from  */
 
979
/* context (toggle)                                             */
841
980
/*--------------------------------------------------------------*/
842
981
 
843
 
void startschemassoc(Widget w, caddr_t clientdata, caddr_t calldata)
 
982
void startschemassoc(xcWidget w, pointertype mode, caddr_t calldata)
844
983
{
845
 
   if (objectdata->symschem != NULL)
 
984
   if ((topobject->symschem != NULL) && (mode == 1))
846
985
      schemdisassoc();
 
986
   else if ((topobject->symschem != NULL) && (mode == 0)) {
 
987
      Wprintf("Refusing to undo current association.");
 
988
   }
847
989
   else {
848
990
      eventmode = ASSOC_MODE;
849
 
      if (objectdata->schemtype == SCHEMATIC) {
 
991
      if (topobject->schemtype == SCHEMATIC) {
850
992
         /* Find a symbol to associate */
851
993
         startcatalog(w, LIBLIB, NULL);
852
994
         Wprintf("Click on library page, then symbol to associate.");
863
1005
/* Callback procedures on the schematic/symbol buttons.         */
864
1006
/*--------------------------------------------------------------*/
865
1007
 
866
 
void schemassoc(objectptr schemobj, objectptr symbolobj)
 
1008
Boolean schemassoc(objectptr schemobj, objectptr symbolobj)
867
1009
{
868
1010
   if (eventmode != ASSOC_MODE) {
869
1011
      Wprintf("Cannot make (dis)association in this mode");
 
1012
#if TCL_WRAPPER
 
1013
      Tcl_SetResult(xcinterp, "Cannot make association in this mode.", NULL);
 
1014
#endif
 
1015
      return False;
870
1016
   }
871
1017
   else if (schemobj->symschem != NULL || symbolobj->symschem != NULL) {
872
1018
      Wprintf("Both objects must be disassociated first.");
 
1019
#if TCL_WRAPPER
 
1020
      Tcl_SetResult(xcinterp, "Both objects must be disassociated first.", NULL);
 
1021
#endif
 
1022
      return False;
873
1023
   }
874
1024
   else {
875
1025
      schemobj->symschem = symbolobj;
882
1032
 
883
1033
      /* Ensure that schematic (page) name is unique */
884
1034
      while (checkpagename(schemobj) < 0);
885
 
   
886
1035
      setsymschem();    /* Set buttons and menu items appropriately */
887
1036
   }
 
1037
   return True;
888
1038
}
889
1039
 
890
1040
#endif