Jspice3
hypertxt.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f4 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1994 Stephen R. Whiteley
5 ****************************************************************************/
6 
7 #include "spice.h"
8 #include "sced.h"
9 #include "scedmacs.h"
10 
11 /* reference table head */
12 #define hyBase ((struct hyEnt**)Parameters.kpCellDesc->sHY)
13 
14 char *
16 
17 /* return an expanded string with up to date entries */
18 struct hprlist *h;
19 {
20  struct hprlist *hh;
21  char buf[BSIZE_SP], *s;
22 
23  buf[0] = '\0';
24  for (hh = h; hh; hh = hh->hlNext) {
25  s = HYgetentry(hh);
26  if (!s)
27  strcat(buf,"<unknown>");
28  else {
29  strcat(buf,s);
30  txfree(s);
31  }
32  }
33  return (copy(buf));
34 }
35 
36 
37 char *
39 
40 /* return an expanded string with ascii encoded entries */
41 struct hprlist *h;
42 {
43  struct hprlist *hh;
44  char buf[BSIZE_SP];
45  char tbuf[BSIZE_SP];
46 
47  buf[0] = '\0';
48  for (hh = h; hh; hh = hh->hlNext) {
49  if (hh->hlRefType == HY_TEXT) {
50  strcat(buf,hh->hlText);
51  }
52  else {
53  sprintf(tbuf,"(||%d:%d %d||)",
54  hh->hlRefType,hh->hlEnt->hyX,hh->hlEnt->hyY);
55  strcat(buf,tbuf);
56  }
57  }
58  return (copy(buf));
59 }
60 
61 
62 struct hprlist *
64 
65 /* return a hypertext list from ascii encoded string */
66 char *str;
67 {
68  struct hprlist *hh, *h0 = NULL;
69  char *s, *t, *tt;
70  int i;
71 
72  s = str;
73  for (;;) {
74  for (t = s;
75  *t && (*t != '(' || *(t+1) != '|' || *(t+2) != '|'); t++) ;
76  if (!*t)
77  break;
78  tt = t - 1;
79  if (tt >= s) {
80  tt++;
81  if (!h0)
82  h0 = hh = alloc(hprlist);
83  else {
84  hh->hlNext = alloc(hprlist);
85  hh = hh->hlNext;
86  }
87  hh->hlRefType = HY_TEXT;
88  hh->hlText = tmalloc(tt - s + 1);
89  strncpy(hh->hlText,s,tt-s);
90  hh->hlText[tt-s] = '\0';
91  }
92  if (!h0)
93  h0 = hh = alloc(hprlist);
94  else {
95  hh->hlNext = alloc(hprlist);
96  hh = hh->hlNext;
97  }
98  /* just store coords in hyEnt, will fill in rest later */
99  hh->hlEnt = alloc(hyEnt);
100  HYadd(hh->hlEnt);
101  sscanf(t+3,"%d:%d %d",
102  &hh->hlRefType,&hh->hlEnt->hyX,&hh->hlEnt->hyY);
103  hh->hlEnt->hyRefType = hh->hlRefType;
104  s = t+3;
105  while (*s && *s != ')') s++;
106  if (!*s)
107  break;
108  s++;
109  }
110  if (*s) {
111  if (!h0)
112  h0 = hh = alloc(hprlist);
113  else {
114  hh->hlNext = alloc(hprlist);
115  hh = hh->hlNext;
116  }
117  hh->hlRefType = HY_TEXT;
118  hh->hlText = copy(s);
119  }
120  return (h0);
121 }
122 
123 
124 char *
126 
127 /* expand a hypertext entry */
128 struct hprlist *h;
129 {
130  switch (h->hlRefType) {
131  case HY_TEXT:
132  return (copy(h->hlText));
133  case HY_NODE:
134  case HY_BRAN:
135  case HY_DEVN:
136  if (h->hlEnt->hyRefType == HY_BOGUS)
137  return (NULL);
138  return (GPgetString(h->hlEnt));
139  default:
140  return (NULL);
141  }
142 }
143 
144 
145 struct hprlist *
147 
148 /* copy a hypertext list */
149 struct hprlist *h;
150 {
151  struct hprlist *hh, *h0 = NULL, *h1;
152 
153  for (hh = h; hh; hh = hh->hlNext) {
154  if (!h0)
155  h0 = h1 = alloc(hprlist);
156  else {
157  h1->hlNext = alloc(hprlist);
158  h1 = h1->hlNext;
159  }
160  h1->hlRefType = hh->hlRefType;
161  if (hh->hlRefType == HY_TEXT) {
162  if (hh->hlText)
163  h1->hlText = copy(hh->hlText);
164  }
165  else if (hh->hlEnt) {
166  h1->hlEnt = HYcopyEnt(hh->hlEnt);
167  HYadd(h1->hlEnt);
168  }
169  }
170  return (h0);
171 }
172 
173 
174 struct hyEnt *
176 
177 struct hyEnt *hent;
178 {
179  struct hyEnt *newh;
180  struct parent *p, *pp;
181 
182  newh = alloc(hyEnt);
183  if (!hent) {
184  newh->hyRefType = HY_BOGUS;
185  return (newh);
186  }
187  *newh = *hent;
188  newh->hyParent = NULL;
189 
190  for (p = hent->hyParent; p; p = p->pNext) {
191  if (newh->hyParent == NULL)
192  newh->hyParent = pp = alloc(parent);
193  else {
194  pp->pNext = alloc(parent);
195  pp = pp->pNext;
196  }
197  pp->pPointer = p->pPointer;
198  pp->pOldPointer = p->pOldPointer;
199  }
200  return (newh);
201 }
202 
203 
204 void
206 
207 /* free a hypertext list */
208 struct hprlist *h;
209 {
210  struct hprlist *hh;
211  struct parent *p, *pnext;
212 
213  for ( ; h; h = hh) {
214  hh = h->hlNext;
215  txfree(h->hlText);
216  if (h->hlEnt) {
217  HYdel(h->hlEnt);
218  for (p = h->hlEnt->hyParent; p; p = pnext) {
219  pnext = p->pNext;
220  txfree((char*)p);
221  }
222  txfree((char*)h->hlEnt);
223  }
224  txfree((char*)h);
225  }
226 }
227 
228 
229 /*********************************************************************
230  *
231  * Hypertext input editor.
232  *
233  *********************************************************************/
234 
235 /* cursor height */
236 #define CURHT 1
237 
238 struct sHtxt {
239  int c; /* character, if type == HY_TEXT */
240  int type; /* one of HY_... TEXT, NODE, BRAN, DEVN, END */
241  struct hyEnt *ent; /* point struct for NODE, BRAN, DEVN */
242  char *str; /* string for NODE, BRAN, DEVN */
243 };
244 
245 /* static storage for edit params (allows redraw) */
246 struct sEdit {
247  bool active; /* true when editing */
248  int x,y; /* lower left coords of string */
249  int fg, bg, cc, hc; /* fore, back, cursor, and highlight colors */
250  int col; /* current cursor column */
251  int cwid; /* current cursor width in cols */
252  struct sHtxt txt[256]; /* storage for input */
253 };
254 static struct sEdit HY;
255 
256 #define DRAW 1
257 #define UNDRAW 0
258 
259 #ifdef __STDC__
260 static bool hyeditor(void);
261 static void hydelcol(int,int);
262 static void hysetcol(int);
263 static void hytext(int,int);
264 static void hycursor(int);
265 static struct hprlist *hylist(void);
266 static struct sHtxt *input(void);
267 #else
268 static bool hyeditor();
269 static void hydelcol();
270 static void hysetcol();
271 static void hytext();
272 static void hycursor();
273 static struct hprlist *hylist();
274 static struct sHtxt *input();
275 #endif
276 
277 
278 char *
279 KbEdit(s,x,y,bg,fg,cc)
280 
281 /* String editing */
282 /*
283  * s Initial string to edit.
284  * x,y Lower left coordinates.
285  * bg,fg Background and foreground colors.
286  * cc Color at cursor location.
287  */
288 char *s;
289 int x, y, bg, fg, cc;
290 {
291  int i;
292  static char editbuf[256];
293  char *t, *tt, *end;
294 
295  HY.bg = bg;
296  HY.fg = fg;
297  HY.cc = cc;
298  HY.hc = cc;
299  HY.x = x;
300  HY.y = y;
301 
302  i = 0;
303  for (t = s; t && *t; t++) {
304  HY.txt[i].c = *t;
305  HY.txt[i].type = HY_TEXT;
306  i++;
307  if (i == 255)
308  break;
309  }
310  HY.txt[i].type = HY_END;
311  if (hyeditor())
312  return (NULL);
313  t = editbuf;
314  end = t + 255;
315  for (i = 0; i < 256; i++) {
316  if (HY.txt[i].type == HY_END)
317  break;
318  if (HY.txt[i].type == HY_TEXT) {
319  *t++ = HY.txt[i].c;
320  }
321  else {
322  tt = HY.txt[i].str;
323  if (tt) {
324  while (*tt != '\0') {
325  *t++ = *tt++;
326  if (t >= end)
327  break;
328  }
329  }
330  }
331  if (t >= end)
332  break;
333  }
334  *t = '\0';
335  hydelcol(0,256);
336  return (editbuf);
337 }
338 
339 
340 struct hprlist *
341 HYedit(h,x,y,bg,fg,cc,hc)
342 
343 /* Hypertext list editing */
344 /*
345  * h Initial hypertext list to edit.
346  * x,y Lower left coordinates.
347  * bg,fg Background and foreground colors.
348  * cc Color at cursor location.
349  * hc Highlighting color for hypertext references.
350  */
351 struct hprlist *h;
352 int x, y, bg, fg, cc, hc;
353 {
354  struct hprlist *hh;
355  char *s;
356  int i, j, k;
357 
358  HY.bg = bg;
359  HY.fg = fg;
360  HY.cc = cc;
361  HY.hc = hc;
362  HY.x = x;
363  HY.y = y;
364 
365  for (i = 0,hh = h; hh; hh = hh->hlNext) {
366  if (hh->hlRefType == HY_TEXT) {
367  k = strlen(hh->hlText);
368  for (j = 0; j < k; j++) {
369  HY.txt[i].c = hh->hlText[j];
370  HY.txt[i].type = HY_TEXT;
371  HY.txt[i].ent = NULL;
372  HY.txt[i].str = NULL;
373  i++;
374  }
375  }
376  else {
377  HY.txt[i].type = hh->hlRefType;
378  HY.txt[i].c = '\0';
379  s = HYgetentry(hh);
380  if (s)
381  HY.txt[i].str = s;
382  else
383  HY.txt[i].str = copy("<unknown>");
384  HY.txt[i].ent = HYcopyEnt(hh->hlEnt);
385  i++;
386  }
387  if (i >= 256) {
388  i = 255;
389  break;
390  }
391  }
392  HY.txt[i].type = HY_END;
393  if (hyeditor())
394  return (NULL);
395  return (hylist());
396 }
397 
398 
399 void
401 
402 /* redraw function */
403 int x,y;
404 {
405  int tmp;
406 
407  if (!HY.active) return;
408  HY.x = x;
409  HY.y = y;
410  hycursor(DRAW);
411  tmp = HY.col;
412  HY.col = 0;
413  hytext(DRAW,-1);
414  HY.col = tmp;
415 }
416 
417 
418 void
420 
421 /* draw a text cursor, like the editor */
422 int x,y;
423 {
425 }
426 
427 
428 static bool
430 
431 /* hypertext editor core */
432 {
433  struct sHtxt *hret;
434  int i;
435 
436  HY.active = true;
437  HY.col = 0;
438 
439  hysetcol(0);
440  hycursor(DRAW);
441  hytext(DRAW,-1);
442 
443  for (;;) {
444  hret = input();
445 
446  if (hret->type == HY_TEXT) {
447  if (hret->c == '\r')
448  break;
449  if (hret->c == ARROW_RT) {
450  /* right arrow */
451  if (HY.txt[HY.col].type == HY_END) continue;
452  hycursor(UNDRAW);
453  hytext(DRAW,1);
454  hysetcol(HY.col+1);
455  hycursor(DRAW);
456  hytext(DRAW,1);
457  continue;
458  }
459  if (hret->c == ARROW_LT) {
460  /* left arrow */
461  if (HY.col <= 0) continue;
462  hycursor(UNDRAW);
463  hytext(DRAW,1);
464  hysetcol(HY.col-1);
465  hycursor(DRAW);
466  hytext(DRAW,1);
467  continue;
468  }
469  if (hret->c == '\b') {
470  /* backspace */
471  if (HY.col == 0) continue;
472  hycursor(UNDRAW);
473  hysetcol(HY.col-1);
474  hytext(UNDRAW,-1);
475  hydelcol(HY.col,1);
476  for (i = HY.col; ; i++) {
477  HY.txt[i] = HY.txt[i+1];
478  if (HY.txt[i].type == HY_END)
479  break;
480  }
481  hytext(DRAW,-1);
482  hysetcol(HY.col);
483  hycursor(DRAW);
484  hytext(DRAW,1);
485  continue;
486  }
487  if (hret->c == 339 || hret->c == 127) {
488  /* DEL, 339 in DOS */
489  if (HY.txt[HY.col].type == HY_END) continue;
490  hycursor(UNDRAW);
491  hytext(UNDRAW,-1);
492  hydelcol(HY.col,1);
493  for (i = HY.col; ; i++) {
494  HY.txt[i] = HY.txt[i+1];
495  if (HY.txt[i].type == HY_END)
496  break;
497  }
498  hytext(DRAW,-1);
499  hysetcol(HY.col);
500  hycursor(DRAW);
501  hytext(DRAW,1);
502  continue;
503  }
504  if (hret->c == '\025' ||
505  hret->c == '\030' ||
506  hret->c == '\033') {
507  /* '\025':^U, '\030':^X, '\033':ESC */
508  hycursor(UNDRAW);
509  HY.col = 0;
510  HY.cwid = 1;
511  hytext(UNDRAW,-1);
512  hydelcol(0,256);
513  HY.txt[0].type = HY_END;
514 
515  if (hret->c == '\033') {
516  HY.active = false;
517  return (true);
518  }
519  hycursor(DRAW);
520  continue;
521  }
522  if (hret->c > 255)
523  continue;
524  if (((char) hret->c < ' ') || ((char) hret->c > '~'))
525  continue;
526  }
527  hycursor(UNDRAW);
528  hytext(UNDRAW,-1);
529  for (i = HY.col; i < 256; i++) {
530  if (HY.txt[i].type == HY_END)
531  break;
532  }
533  i++;
534  if (i >= 256) {
535  i = 255;
536  hydelcol(254,2);
537  HY.txt[254].type = HY_END;
538  }
539  while (i > HY.col) {
540  HY.txt[i] = HY.txt[i-1];
541  i--;
542  }
543  HY.txt[HY.col] = *hret;
544  hytext(DRAW,-1);
545  hysetcol(HY.col+1);
546  hycursor(DRAW);
547  hytext(DRAW,1);
548  }
549  hycursor(UNDRAW);
550  hytext(DRAW,1);
551  HY.active = false;
552  return (false);
553 }
554 
555 
556 static void
557 hydelcol(col,num)
558 
559 /* delete the current logical column */
560 int col,num;
561 {
562  struct parent *p, *pnext;
563 
564  if (col < 0 || col > 255)
565  return;
566  if (num < 0)
567  return;
568  num += col;
569  if (num > 256)
570  num = 256;
571 
572  for ( ; col < num; col++) {
573  tfree(HY.txt[col].str);
574  HY.txt[col].type = HY_END;
575  if (HY.txt[col].ent) {
576  for (p = HY.txt[col].ent->hyParent; p; p = pnext) {
577  pnext = p->pNext;
578  txfree((char*)p);
579  }
580  tfree(HY.txt[col].ent);
581  }
582  HY.txt[col].c = 0;
583  }
584 }
585 
586 
587 static void
589 
590 /* set the current logical column */
591 int col;
592 {
593  if (col < 0 || col > 255)
594  return;
595  switch (HY.txt[col].type) {
596  case HY_TEXT:
597  case HY_END:
598  HY.cwid = 1;
599  break;
600  case HY_NODE:
601  case HY_BRAN:
602  case HY_DEVN:
603  if (HY.txt[col].str)
604  HY.cwid = strlen(HY.txt[col].str);
605  else
606  HY.cwid = 1;
607  break;
608  default:
609  /* points at garbage, make it an end record */
610  HY.txt[col].type = HY_END;
611  HY.cwid = 1;
612  }
613  HY.col = col;
614 }
615 
616 
617 static void
618 hytext(draw,ncols)
619 
620 /* display ncols of hypertext string, starting at the current
621  * logical column, if ncols is < 0, show to end
622  */
623 int draw, ncols;
624 {
625  int i, k, realcol, endcol;
626  char buf[BSIZE_SP];
627 
628  realcol = 0;
629  for (i = 0; i < HY.col; i++) {
630  if (HY.txt[i].type == HY_END)
631  break;
632  if (HY.txt[i].type == HY_TEXT)
633  realcol++;
634  else
635  realcol += strlen(HY.txt[i].str);
636  }
637  if (i < HY.col)
638  return;
639 
640  k = 0;
641  if (ncols < 0)
642  endcol = 255;
643  else {
644  endcol = i + ncols;
645  if (endcol > 255)
646  endcol = 255;
647  }
648  for (;;) {
649  if (HY.txt[i].type == HY_END || i == endcol) {
650  if (k) {
651  buf[k] = '\0';
652  if (draw)
653  DevSetColor(HY.fg);
654  else
655  DevSetColor(HY.bg);
656  DevText(buf,HY.x + realcol*currentgraph->fontwidth,HY.y);
657  }
658  break;
659  }
660  if (HY.txt[i].type == HY_TEXT) {
661  buf[k] = HY.txt[i].c;
662  k++;
663  }
664  else {
665  if (k) {
666  buf[k] = '\0';
667  if (draw)
668  DevSetColor(HY.fg);
669  else
670  DevSetColor(HY.bg);
671  DevText(buf,HY.x + realcol*currentgraph->fontwidth,HY.y);
672  realcol += k;
673  k = 0;
674  }
675  if (draw)
676  DevSetColor(HY.hc);
677  else
678  DevSetColor(HY.bg);
679  DevText(HY.txt[i].str,
680  HY.x + realcol*currentgraph->fontwidth,HY.y);
681  realcol += strlen(HY.txt[i].str);
682  }
683  i++;
684  }
685 }
686 
687 
688 static void
690 
691 /* erase or draw the cursor */
692 int draw;
693 {
694  int i, x, y, w, realcol;
695 
696  realcol = 0;
697  for (i = 0; i < HY.col; i++) {
698  if (HY.txt[i].type == HY_END) {
699  realcol++;
700  break;
701  }
702  if (HY.txt[i].type == HY_TEXT)
703  realcol++;
704  else
705  realcol += strlen(HY.txt[i].str);
706  }
707  x = HY.x + realcol * currentgraph->fontwidth;
708  y = HY.y;
709  w = HY.cwid * currentgraph->fontwidth;
710  if (draw)
711  DevSetColor(HY.cc);
712  else
713  DevSetColor(HY.bg);
714  DevBox(x,y,x + w,y + CURHT);
715 }
716 
717 
718 static struct hprlist *
720 
721 /* return hprlist from input queue */
722 {
723  struct hprlist *h, *h0 = NULL;
724  int i, k;
725  char buf[BSIZE_SP];
726 
727  k = 0;
728  for (i = 0; ; i++) {
729 
730  if (HY.txt[i].type == HY_END || i == 255) {
731  if (k) {
732  buf[k] = '\0';
733  if (!h0)
734  h0 = h = alloc(hprlist);
735  else {
736  h->hlNext = alloc(hprlist);
737  h = h->hlNext;
738  }
739  h->hlRefType = HY_TEXT;
740  h->hlText = copy(buf);
741  }
742  if (i == 0) {
743  /* No text, return something to distinguish
744  * from ESC.
745  */
746  h0 = alloc(hprlist);
747  h0->hlRefType = HY_TEXT;
748  h0->hlText = copy("");
749  }
750  break;
751  }
752  if (HY.txt[i].type == HY_TEXT) {
753  buf[k] = HY.txt[i].c;
754  k++;
755  }
756  else {
757  if (k) {
758  buf[k] = '\0';
759  k = 0;
760  if (!h0)
761  h0 = h = alloc(hprlist);
762  else {
763  h->hlNext = alloc(hprlist);
764  h = h->hlNext;
765  }
766  h->hlRefType = HY_TEXT;
767  h->hlText = copy(buf);
768  }
769  if (!h0)
770  h0 = h = alloc(hprlist);
771  else {
772  h->hlNext = alloc(hprlist);
773  h = h->hlNext;
774  }
775  h->hlRefType = HY.txt[i].type;
776  h->hlEnt = HYcopyEnt(HY.txt[i].ent);
777  HYadd(h->hlEnt);
778  }
779  }
780  hydelcol(0,256);
781  return (h0);
782 }
783 
784 
785 static struct sHtxt *
787 
788 /* get character or point return */
789 {
790  static struct sHtxt hret;
793  char *GPstring();
794  struct hyEnt *ent;
795 
796  request.option = point_option;
797  request.fp = (FILE*)0;
798  for (;;) {
799  DevInput(&request, &response);
800  if (response.option == char_option) {
801  hret.c = response.reply.ch;
802  hret.type = HY_TEXT;
803  hret.ent = NULL;
804  hret.str = NULL;
805  return (&hret);
806  }
808  ButtonPress(response.reply.button,response.x,response.y);
809  /* if button1, get string from sced */
810  if (response.reply.button == 1) {
811  hret.str = GPstring(HY_ALL,&ent);
812  if (!hret.str)
813  continue;
814  hret.ent = ent;
815  hret.type = ent->hyRefType;
816  hret.c = 0;
817  return (&hret);
818  }
819  }
820  }
821 }
822 
823 
824 /***********************************************************************
825  *
826  * Routines for updating saved hypertext references if the
827  * underlying element is moved, and otherwise maintaining
828  * the table of references.
829  *
830  ***********************************************************************/
831 
832 
833 void
835 
836 /* Make sure all references have a device pointer attached.
837  * Called after entire circuit has been read in.
838  */
839 {
840  int i;
841  struct hyEnt **hent;
842  char *s;
843 
844  if (hyBase == NULL)
845  return;
846 
847  for (hent = hyBase; *hent; hent++) {
848  if ((*hent)->hyPointer == NULL && (
849  (*hent)->hyRefType == HY_NODE ||
850  (*hent)->hyRefType == HY_BRAN ||
851  (*hent)->hyRefType == HY_DEVN)) {
852  s = GPgetString(*hent);
853  txfree(s);
854  }
855  }
856 }
857 
858 
859 void
861 
862 /* add ent to the hypertext database */
863 struct hyEnt *ent;
864 {
865  int i;
866 
867  if (hyBase == NULL) {
868  /* DEC barfs
869  hyBase = (struct hyEnt **)
870  */
872 
873  tmalloc(2*sizeof(struct hyEnt*));
874  hyBase[0] = ent;
875  hyBase[1] = NULL;
876  return;
877  }
878  for (i = 0; hyBase[i]; i++) {
879  if (hyBase[i] == ent)
880  return;
881  }
882 
883  /* DEC barfs
884  hyBase = (struct hyEnt**)
885  */
887 
888  trealloc((char*)hyBase,(i+2)*sizeof(struct hyEnt*));
889  hyBase[i] = ent;
890  hyBase[i+1] = NULL;
891 }
892 
893 
894 void
896 
897 /* delete ent from the hypertext database */
898 struct hyEnt *ent;
899 {
900  int i;
901 
902  if (hyBase == NULL)
903  return;
904  for (i = 0; hyBase[i]; i++) {
905  if (hyBase[i] == ent)
906  break;
907  }
908  if (hyBase[i] == NULL)
909  return;
910  for ( ; hyBase[i]; i++)
911  hyBase[i] = hyBase[i+1];
912 }
913 
914 
915 void
916 HYtransform(Pointer,NewPointer)
917 
918 /* Fix references attached to objects being moved. Note that this only
919  * has to be done for top level references, as the parent list supplies
920  * the transforms for lower level references. Set a flag so that this
921  * can be undone.
922  */
923 struct o *Pointer,*NewPointer;
924 {
925  struct hyEnt **hent;
926  long X,Y,X1,Y1;
927 
928  if (!hyBase)
929  return;
930 
931  for (hent = hyBase; *hent; hent++) {
932 
933  if (Pointer == (*hent)->hyPointer) {
934  (*hent)->hyOldX = (*hent)->hyX;
935  (*hent)->hyOldY = (*hent)->hyY;
936  (*hent)->hyOldPointer = (*hent)->hyPointer;
937  TPoint(&((*hent)->hyX),&((*hent)->hyY));
938  (*hent)->hyPointer = NewPointer;
939  (*hent)->hyUndo = True;
940 
941  switch ((*hent)->hyOrient) {
942  default:
943  case MARK_NONE:
944  continue;
945  case MARK_DN:
946  X = 0;
947  Y = -1;
948  break;
949  case MARK_RT:
950  X = 1;
951  Y = 0;
952  break;
953  case MARK_UP:
954  X = 0;
955  Y = 1;
956  break;
957  case MARK_LT:
958  X = -1;
959  Y = 0;
960  break;
961  }
962  X1 = 0;
963  Y1 = 0;
964  TPoint(&X,&Y);
965  TPoint(&X1,&Y1);
966  X -= X1;
967  Y -= Y1;
968  (*hent)->hyOldOrient = (*hent)->hyOrient;
969 
970  if (X == 0) {
971  if (Y == 1)
972  (*hent)->hyOrient = MARK_UP;
973  else
974  (*hent)->hyOrient = MARK_DN;
975  }
976  else {
977  if (X == 1)
978  (*hent)->hyOrient = MARK_RT;
979  else
980  (*hent)->hyOrient = MARK_LT;
981  }
982  }
983  }
984 }
985 
986 
987 void
988 HYtransformStretch(Pointer,NewPointer,RefX,RefY,NewX,NewY)
989 
990 /* Fix references attached to wires that are being stretched. */
991 struct o *Pointer,*NewPointer;
992 long RefX,RefY,NewX,NewY;
993 {
994  struct hyEnt **hent;
995  struct p *p,*q,*ptmp;
996  int i;
997  double x1,y1,d,d0;
998 
999  if (Pointer->oType != CDWIRE)
1000  return;
1001  if (!hyBase)
1002  return;
1003 
1004  for (hent = hyBase; *hent; hent++) {
1005 
1006  if ((*hent)->hyPointer != Pointer)
1007  continue;
1008  p = ((struct w *)Pointer->oRep)->wPath;
1009  for (; p; p = q) {
1010  q = p->pSucc;
1011  if (q == NULL) break;
1012  ptmp = q->pSucc;
1013  q->pSucc = NULL;
1014  if (InPath(20,p,(*hent)->hyX,(*hent)->hyY) == NULL) {
1015  q->pSucc = ptmp;
1016  continue;
1017  }
1018  if (RefX == p->pX && RefY == p->pY) {
1019  x1 = q->pX - (*hent)->hyX;
1020  y1 = q->pY - (*hent)->hyY;
1021  }
1022  else if (RefX == q->pX && RefY == q->pY) {
1023  x1 = (*hent)->hyX - p->pX;
1024  y1 = (*hent)->hyY - p->pY;
1025  }
1026  else {
1027  q->pSucc = ptmp;
1028  return;
1029  }
1030  d = x1*x1 + y1*y1;
1031  x1 = q->pX - p->pX;
1032  y1 = q->pY - p->pY;
1033  d0 = x1*x1 + y1*y1;
1034  d = sqrt(d/d0);
1035  (*hent)->hyOldX = (*hent)->hyX;
1036  (*hent)->hyOldY = (*hent)->hyY;
1037  (*hent)->hyOldPointer = (*hent)->hyPointer;
1038  (*hent)->hyX += (NewX-RefX)*d;
1039  (*hent)->hyY += (NewY-RefY)*d;
1040  (*hent)->hyPointer = NewPointer;
1041  (*hent)->hyUndo = True;
1042  q->pSucc = ptmp;
1043  }
1044  }
1045 }
1046 
1047 
1048 void
1050 
1051 {
1052  struct hyEnt **hent;
1053 
1054  if (!hyBase)
1055  return;
1056 
1057  for (hent = hyBase; *hent; hent++) {
1058 
1059  if ((*hent)->hyUndo) {
1060  (*hent)->hyX = (*hent)->hyOldX;
1061  (*hent)->hyY = (*hent)->hyOldY;
1062  (*hent)->hyPointer = (*hent)->hyOldPointer;
1063  (*hent)->hyOrient = (*hent)->hyOldOrient;
1064  (*hent)->hyUndo = False;
1065  }
1066  }
1067 }
1068 
1069 
1070 void
1072 
1073 {
1074  struct hyEnt **hent;
1075 
1076  if (!hyBase)
1077  return;
1078 
1079  for (hent = hyBase; *hent; hent++)
1080  (*hent)->hyUndo = False;
1081 }
1082 
1083 
1084 void
1086 
1087 /* The object referenced by Pointer is being deleted.
1088  * Null the references.
1089  */
1090 struct o *Pointer;
1091 {
1092  struct parent *p, *pnext;
1093  struct hyEnt **hent, **h0;
1094 
1095  if (!hyBase)
1096  return;
1097 
1098  for (hent = hyBase; *hent; hent = h0) {
1099  h0 = hent + 1;
1100 
1101  if ((*hent)->hyPointer != Pointer) {
1102 
1103  for (p = (*hent)->hyParent; p; p = p->pNext)
1104  if (p->pPointer == Pointer)
1105  break;
1106  if (!p)
1107  continue;
1108  }
1109  for (p = (*hent)->hyParent; p; p = pnext) {
1110  pnext = p->pNext;
1111  free(p);
1112  }
1113  (*hent)->hyParent = NULL;
1114  (*hent)->hyRefType = HY_BOGUS;
1115  (*hent)->hyPointer = NULL;
1116  (*hent)->hyOldPointer = NULL;
1117  (*hent)->hyOrient = MARK_NONE;
1118  (*hent)->hyUndo = False;
1119  if (GPdeleteGrafRef(*hent)) {
1120  /* *hent was freed */
1121  for ( ; *hent; hent++)
1122  *hent = *(hent+1);
1123  h0--;
1124  }
1125  /* *hent references nothing, user has to fix */
1126  }
1127 }
static char buf[MAXPROMPT]
Definition: arg.c:18
int hlRefType
Definition: sced.h:194
#define BSIZE_SP
Definition: misc.h:19
#define MARK_DN
Definition: scedmacs.h:29
#define CURHT
Definition: hypertxt.c:236
void TPoint()
int struct o * Pointer
Definition: cd.c:1311
Definition: subckt.c:18
void HYinit()
Definition: hypertxt.c:834
#define HY_BRAN
Definition: sced.h:165
int fg
Definition: hypertxt.c:249
void HYfree(struct hprlist *h)
Definition: hypertxt.c:205
Definition: sced.h:172
static struct hprlist * hylist()
Definition: hypertxt.c:719
#define MARK_LT
Definition: scedmacs.h:32
int bg
Definition: hypertxt.c:249
char * str
Definition: hypertxt.c:242
bool active
Definition: hypertxt.c:247
Definition: cddefs.h:119
#define HY_ALL
Definition: sced.h:167
static void hycursor()
struct hprlist * HYcopy(struct hprlist *h)
Definition: hypertxt.c:146
Definition: objects.c:1183
int col
Definition: hypertxt.c:250
void DevSetColor()
Definition: xforms.c:16
#define UNDRAW
Definition: hypertxt.c:257
void DevText()
struct s * kpCellDesc
Definition: sced.h:207
struct hprlist * HYedit(struct hprlist *h, int x, int y, int bg, int fg, int cc, int hc)
Definition: hypertxt.c:341
static struct sHtxt * input()
Definition: hypertxt.c:786
struct hyEnt * HYcopyEnt(struct hyEnt *hent)
Definition: hypertxt.c:175
int cc
Definition: hypertxt.c:249
void HYdel(struct hyEnt *ent)
Definition: hypertxt.c:895
FILE * p
Definition: proc2mod.c:48
struct parent * pNext
Definition: sced.h:175
void HYadd(struct hyEnt *ent)
Definition: hypertxt.c:860
int y
Definition: hypertxt.c:248
char * HYgetentry(struct hprlist *h)
Definition: hypertxt.c:125
Definition: cddefs.h:169
struct o * pPointer
Definition: sced.h:173
long hyY
Definition: sced.h:180
void HYtransformStretch(struct o *Pointer, struct o *NewPointer, long RefX, long RefY, long NewX, long NewY)
Definition: hypertxt.c:988
#define DRAW
Definition: hypertxt.c:256
#define MARK_UP
Definition: scedmacs.h:31
#define hyBase
Definition: hypertxt.c:12
struct hprlist * hlNext
Definition: sced.h:197
#define HY_END
Definition: sced.h:163
char * GPstring()
Definition: cddefs.h:215
Definition: sced.h:193
int ch
Definition: ftegraph.h:196
#define HY_TEXT
Definition: sced.h:168
struct hprlist * HYfromascii(char *str)
Definition: hypertxt.c:63
#define alloc(type)
Definition: cdmacs.h:21
void KbCursor(int x, int y)
Definition: hypertxt.c:419
char * HYtostr(struct hprlist *h)
Definition: hypertxt.c:15
struct sHtxt txt[256]
Definition: hypertxt.c:252
static struct sEdit HY
Definition: hypertxt.c:254
char * copy()
int c
Definition: hypertxt.c:239
union response::@11 reply
long pY
Definition: cddefs.h:216
#define GR_SCED
Definition: ftegraph.h:23
char * tmalloc()
long X
Definition: actions.c:450
int x
Definition: hypertxt.c:248
void DevBox()
struct parent * hyParent
Definition: sced.h:185
int fontwidth
Definition: ftegraph.h:82
Definition: cddefs.h:237
int ButtonPress()
#define HY_NODE
Definition: sced.h:164
#define tfree(x)
Definition: cdmacs.h:22
void txfree()
int hyUndo
Definition: sced.h:189
char * KbEdit(char *s, int x, int y, int bg, int fg, int cc)
Definition: hypertxt.c:279
#define NULL
Definition: spdefs.h:121
int graphtype
Definition: ftegraph.h:31
static bool hyeditor()
Definition: hypertxt.c:429
#define HY_DEVN
Definition: sced.h:166
struct kp Parameters
Definition: init.c:19
int hyRefType
Definition: sced.h:188
long * InPath()
#define True
Definition: scedstub.c:16
static void draw()
void HYdeleteReference(struct o *Pointer)
Definition: hypertxt.c:1085
char * GPgetString()
struct o * pOldPointer
Definition: sced.h:174
static void hydelcol()
char * hlText
Definition: sced.h:195
void HYtransform(struct o *Pointer, struct o *NewPointer)
Definition: hypertxt.c:916
Definition: sced.h:178
void HYundoTransform()
Definition: hypertxt.c:1049
struct hyEnt * hlEnt
Definition: sced.h:196
Definition: cddefs.h:142
#define ARROW_LT
Definition: scedmacs.h:42
int button
Definition: ftegraph.h:198
long pX
Definition: cddefs.h:216
int GPdeleteGrafRef()
void DevInput()
int y
Definition: ftegraph.h:194
#define ARROW_RT
Definition: scedmacs.h:41
int x
Definition: ftegraph.h:193
#define CDWIRE
Definition: cddefs.h:47
struct hyEnt * ent
Definition: hypertxt.c:241
OPTION option
Definition: ftegraph.h:192
int cwid
Definition: hypertxt.c:251
int hc
Definition: hypertxt.c:249
char * HYtoascii(struct hprlist *h)
Definition: hypertxt.c:38
static void hysetcol()
char * sHY
Definition: cddefs.h:134
#define MARK_RT
Definition: scedmacs.h:30
GRAPH * currentgraph
Definition: graphdb.c:21
int type
Definition: hypertxt.c:240
void HYclearUndoFlags()
Definition: hypertxt.c:1071
#define False
Definition: scedstub.c:15
long hyX
Definition: sced.h:179
void KbRepaint(int x, int y)
Definition: hypertxt.c:400
#define HY_BOGUS
Definition: sced.h:169
static void hytext()
Definition: cddefs.h:192
struct p * pSucc
Definition: cddefs.h:217
long Y
Definition: actions.c:450
char * trealloc()
void free()
#define MARK_NONE
Definition: scedmacs.h:28