1 /***************************************************************************
2 SCED - Schematic Capture Editor
3 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
4 Copyright 1990 Regents of the University of California. All rights reserved.
5 Authors: 1981 Giles C. Billingsley (parts of KIC layout editor)
6 1992 Stephen R. Whiteley
7 ****************************************************************************/
8
9 /*
10 * SCED viewport management code.
11 *
12 */
13
14 #include "spice.h"
15 #include "sced.h"
16 #include "scedmacs.h"
17
18 /* for point marks */
19 struct mark {
20 long X;
21 long Y;
22 int Delta;
23 int Type;
24 int Orient;
25 struct mark *next;
26 };
27
28 #ifdef __STDC__
29 static int get_menu_index(MENU*,char*);
30 static void fix_menu_entry_prefix(MENU*,int);
31 static void display_menu_entry(MENU*,int);
32 static void display_selected_entry(MENU*,int);
33 static void mark_object(struct o*);
34 static void show_mark(struct mark*,int);
35 static void gp_mark(int,int,int,int,int,int);
36 static int my_strnicmp(char*,char*,int);
37 #else
38 static int get_menu_index();
39 static void fix_menu_entry_prefix();
40 static void display_menu_entry();
41 static void display_selected_entry();
42 static void mark_object();
43 static void show_mark();
44 static void gp_mark();
45 static int my_strnicmp();
46 #endif
47
48 /***********************************************************************
49 *
50 * Routines used to process cursor data.
51 *
52 *
53 ***********************************************************************/
54
55 /* also see macros in coords.h */
56
57
58 void
PToL(Window,X,Y)59 PToL(Window,X,Y)
60
61 /* convert viewport to window coordinates */
62 struct ka *Window;
63 long *X, *Y;
64 {
65 if (Window == View->kvCoarseWindow) {
66 *X = .5+(*X - View->kvCoarseViewport->kaLeft)/
67 View->kvCoarseRatio;
68 *X += Window->kaLeft;
69 *Y = .5+(*Y - View->kvCoarseViewport->kaBottom)/
70 View->kvCoarseRatio;
71 *Y += Window->kaBottom;
72 }
73 elif (Window == View->kvFineWindow) {
74 *X = .5+(*X - View->kvFineViewport->kaLeft)/
75 View->kvFineRatio;
76 *X += Window->kaLeft;
77 *Y = .5+(*Y - View->kvFineViewport->kaBottom)/
78 View->kvFineRatio;
79 *Y += Window->kaBottom;
80 }
81 else {
82 *X = *Y = 0;
83 return;
84 }
85 }
86
87
88 void
ClipToGridPoint(x,y)89 ClipToGridPoint(x,y)
90
91 /* Clip to nearest window grid coordinate */
92 long *x,*y;
93 {
94
95 long k;
96
97 /* snap to grid/2 points */
98 k = Parameters.kpGrid/2;
99
100 if (*x > 0)
101 *x = ((*x+k/2)/k)*k;
102 else
103 *x = ((*x-k/2)/k)*k;
104
105 if (*y > 0)
106 *y = ((*y+k/2)/k)*k;
107 else
108 *y = ((*y-k/2)/k)*k;
109 }
110
111
112 /***********************************************************************
113 *
114 * Routines to dislay and manipulate menus.
115 *
116 *
117 ***********************************************************************/
118
119
120 void
ShowCommandMenu()121 ShowCommandMenu()
122
123 {
124 if (Parameters.kpMenu == BASICMENU) {
125 ShowMenu(BasicMenu);
126 return;
127 }
128 if (Parameters.kpMenu == AMBIGUITYMENU) {
129 ShowMenu(AmbiguityMenu);
130 return;
131 }
132 }
133
134
135 void
ShowMenu(Menu)136 ShowMenu(Menu)
137
138 MENU *Menu;
139 {
140 int Int1,Int2;
141
142 /*
143 * Erase the entire menu viewport.
144 */
145 OutlineText((int)MenuViewport.kaLeft,(int)MenuViewport.kaBottom,
146 (int)MenuViewport.kaRight,(int)MenuViewport.kaTop,FILL,ERASE,0);
147 /*
148 * Display Menu Table
149 */
150 for (Int1 = 0; ; Int1++) {
151 if (Menu[Int1].mEntry == NULL) break;
152 if (Menu[Int1].mActive)
153 display_selected_entry(Menu,Int1);
154 else
155 display_menu_entry(Menu,Int1);
156 }
157 if (Menu == BasicMenu) {
158 Int2 = Int1;
159 if (Int2 < MenuViewport.kaY)
160 Int2 = MenuViewport.kaY;
161 for (Int1 = 0; ; Int1++) {
162 if (DeviceMenu[Int1].mEntry == NULL) break;
163 if (DeviceMenu[Int1].mActive)
164 display_selected_entry(DeviceMenu-Int2,Int1+Int2);
165 else
166 display_menu_entry(DeviceMenu-Int2,Int1+Int2);
167 }
168 }
169 DevUpdate();
170 }
171
172
173 MENU *
GetCurrentMenu()174 GetCurrentMenu()
175
176 {
177 if (Parameters.kpMenu == BASICMENU)
178 return (BasicMenu);
179 if (Parameters.kpMenu == AMBIGUITYMENU)
180 return (AmbiguityMenu);
181 return (NULL);
182 }
183
184
185 void
AlterMenuEntries(Word1,Word2)186 AlterMenuEntries(Word1,Word2)
187
188 /* Change all the entries of Word1 in the menus to Word2. */
189 char *Word1,*Word2;
190 {
191 int i;
192
193 i = get_menu_index(BasicMenu,Word1);
194 if (i >= 0) {
195 BasicMenu[i].mEntry = Word2;
196 fix_menu_entry_prefix(BasicMenu,i);
197 }
198 i = get_menu_index(AmbiguityMenu,Word1);
199 if (i >= 0) {
200 AmbiguityMenu[i].mEntry = Word2;
201 fix_menu_entry_prefix(AmbiguityMenu,i);
202 }
203 }
204
205
206 void
MenuSelect(Selection)207 MenuSelect(Selection)
208
209 char *Selection;
210 {
211 int Int1;
212
213 Int1 = get_menu_index(BasicMenu,Selection);
214 if (Int1 >= 0) {
215 BasicMenu[Int1].mActive = True;
216 if (Parameters.kpMenu == BASICMENU)
217 display_selected_entry(BasicMenu,Int1);
218 }
219 Int1 = get_menu_index(AmbiguityMenu,Selection);
220 if (Int1 >= 0) {
221 AmbiguityMenu[Int1].mActive = True;
222 if (Parameters.kpMenu == AMBIGUITYMENU)
223 display_selected_entry(AmbiguityMenu,Int1);
224 }
225 }
226
227
228 void
MenuDeselect(Selection)229 MenuDeselect(Selection)
230
231 char *Selection;
232 {
233 int Int1;
234
235 Int1 = get_menu_index(BasicMenu,Selection);
236 if (Int1 >= 0) {
237 BasicMenu[Int1].mActive = False;
238 if (Parameters.kpMenu == BASICMENU)
239 display_menu_entry(BasicMenu,Int1);
240 }
241 Int1 = get_menu_index(AmbiguityMenu,Selection);
242 if (Int1 >= 0) {
243 AmbiguityMenu[Int1].mActive = False;
244 if (Parameters.kpMenu == AMBIGUITYMENU)
245 display_menu_entry(AmbiguityMenu,Int1);
246 }
247 }
248
249
250 void
MenuSelectDev(Selection)251 MenuSelectDev(Selection)
252
253 char *Selection;
254 {
255 int Int1,Int2;
256
257 Int1 = get_menu_index(DeviceMenu,Selection);
258 if (Int1 >= 0) {
259 for (Int2 = 0; ; Int2++)
260 if (BasicMenu[Int2].mEntry == NULL) break;
261 if (Int2 < MenuViewport.kaY)
262 Int2 = MenuViewport.kaY;
263 DeviceMenu[Int1].mActive = True;
264 display_selected_entry(DeviceMenu-Int2,Int1+Int2);
265 }
266 }
267
268
269 void
MenuDeselectDev(Selection)270 MenuDeselectDev(Selection)
271
272 char *Selection;
273 {
274 int Int1,Int2;
275
276 Int1 = get_menu_index(DeviceMenu,Selection);
277 if (Int1 >= 0) {
278 for (Int2 = 0; ; Int2++)
279 if (BasicMenu[Int2].mEntry == NULL) break;
280 if (Int2 < MenuViewport.kaY)
281 Int2 = MenuViewport.kaY;
282 DeviceMenu[Int1].mActive = False;
283 display_menu_entry(DeviceMenu-Int2,Int1+Int2);
284 }
285 }
286
287
288 void
FixMenuPrefix(Menu)289 FixMenuPrefix(Menu)
290
291 MENU *Menu;
292 {
293 int i;
294
295 for (i = 0; Menu[i].mEntry; i++)
296 fix_menu_entry_prefix(Menu,i);
297 }
298
299
300 static void
fix_menu_entry_prefix(Menu,Index)301 fix_menu_entry_prefix(Menu,Index)
302
303 /* Find a unique prefix for the menu entry and save it
304 * in the mPrefix field.
305 */
306 MENU *Menu;
307 int Index;
308 {
309 int Count;
310 char m1[32], m2[32];
311 int j,k;
312
313 memset(Menu[Index].mPrefix,0,6);
314
315 Count = 1;
316 strcpy(m1,Menu[Index].mEntry);
317 for (j = 0; Menu[j].mEntry; j++) {
318 if (Index == j) continue;
319 strcpy(m2,Menu[j].mEntry);
320 if (cieq(m1,m2)) {
321 if (*Menu[Index].mEntry != ' ')
322 for (k = j; Menu[k].mEntry; k++) {
323 strcpy(Menu[k].mPrefix,Menu[k+1].mPrefix);
324 Menu[k].mEntry = Menu[k+1].mEntry;
325 Menu[k].mActive = Menu[k+1].mActive;
326 }
327 continue;
328 }
329 while (!my_strnicmp(m1,m2,Count))
330 Count++;
331 }
332 if (Count > 5) Count = 5;
333 while (Count--)
334 Menu[Index].mPrefix[Count] = Menu[Index].mEntry[Count];
335 }
336
337
338 static int
get_menu_index(Menu,String)339 get_menu_index(Menu,String)
340
341 MENU *Menu;
342 char *String;
343 {
344 int i = 0;
345
346 while (Menu[i].mEntry != NULL) {
347 if (!strcmp(Menu[i].mEntry,String)) return (i);
348 i++;
349 }
350 return (-1);
351 }
352
353
354 static void
display_menu_entry(Menu,Index)355 display_menu_entry(Menu,Index)
356
357 MENU *Menu;
358 int Index;
359 {
360 char MenuSelection[8],*prefix;
361 int Left;
362
363 strncpy(MenuSelection,Menu[Index].mEntry,MenuViewport.kaX);
364 MenuSelection[MenuViewport.kaX] = '\0';
365 prefix = Menu[Index].mPrefix;
366
367 Index += MenuViewport.kaTop;
368 Left = MenuViewport.kaLeft;
369 if (Index > MenuViewport.kaY) {
370 Left += 6;
371 Index -= MenuViewport.kaY;
372 }
373 /*
374 * Erase highlight box.
375 */
376 OutlineText(Left,Index,Left+4,Index,FILL,ERASE,0);
377 /*
378 * Redisplay menu selection.
379 */
380 DevSetColor(MenuTextColor);
381 FBText(ROW_COLUMN,Index,Left,MenuSelection);
382
383 DevSetColor(MenuTextPrefixColor);
384 FBText(ROW_COLUMN,Index,Left,prefix);
385 }
386
387
388 static void
display_selected_entry(Menu,Index)389 display_selected_entry(Menu,Index)
390
391 MENU *Menu;
392 int Index;
393 {
394 char MenuSelection[8], *prefix;
395 int Left;
396
397 strncpy(MenuSelection,Menu[Index].mEntry,MenuViewport.kaX);
398 MenuSelection[MenuViewport.kaX] = '\0';
399 prefix = Menu[Index].mPrefix;
400
401 Index += MenuViewport.kaTop;
402 Left = MenuViewport.kaLeft;
403 if (Index > MenuViewport.kaY) {
404 Left += 6;
405 Index -= MenuViewport.kaY;
406 }
407 /*
408 * Erase Menu command
409 */
410 OutlineText(Left,Index,Left+4,Index,FILL,ERASE,0);
411
412 /*
413 * Display highlight box.
414 */
415 OutlineText(Left,Index,Left+4,Index,FILL,DISPLAY,
416 MenuHighlightingColor);
417
418 /*
419 * Redisplay menu selection.
420 */
421 DevSetColor(MenuSelectedColor);
422 FBText(ROW_COLUMN,Index,Left,MenuSelection);
423
424 DevSetColor(MenuSelectedPrefixColor);
425 FBText(ROW_COLUMN,Index,Left,prefix);
426 }
427
428
429 /***********************************************************************
430 *
431 * Routines to display message text.
432 *
433 *
434 ***********************************************************************/
435
436 static char BackPrompt[200];
437 static char BackColor;
438
439
440 void
ShowPrompt(Prompt)441 ShowPrompt(Prompt)
442
443 char *Prompt;
444 {
445 ShowPromptWithColor(Prompt,PromptTextColor);
446 }
447
448
449 void
ShowPromptAndWait(cp)450 ShowPromptAndWait(cp)
451
452 char *cp;
453 {
454 putchar('\007');
455 fflush(stdout);
456 ShowPrompt(cp);
457 sleep(2);
458 }
459
460
461 void
ShowPromptWithColor(Prompt,Color)462 ShowPromptWithColor(Prompt,Color)
463
464 char *Prompt;
465 int Color;
466 {
467 /*
468 * Implements a basic scroller in a prompt window.
469 * Displays MORE when window is full and continues when
470 * user hits and key.
471 */
472 char *cp;
473 char *TypeIn;
474 char buffer[200];
475 int Int1;
476 int Row;
477
478 Row = gi_numtextrows;
479 ErasePrompt();
480 DevSetColor(Color);
481 BackColor = Color;
482 cp = Prompt;
483 Int1 = 0;
484 while (*cp != EOS) {
485 buffer[Int1] = *cp++;
486 if (buffer[Int1] == '\n')
487 buffer[Int1] = EOS;
488 Int1++;
489 if (*cp == EOS) {
490 buffer[Int1++] = EOS;
491 strcpy(BackPrompt,buffer);
492 FBText(ROW_COLUMN,Row,1,buffer);
493 DevUpdate();
494 Parameters.kpLastCursorColumn = strlen(buffer) + 1;
495 }
496 elif ((Int1 > gi_numtextcols - 8) Or (Int1 > 190)) {
497 sprintf(&buffer[Int1]," MORE");
498 strcpy(BackPrompt,buffer);
499 FBText(ROW_COLUMN,Row,1,buffer);
500 DevUpdate();
501 Parameters.kpLastCursorColumn = strlen(buffer);
502 (void)FBGetchar(ERASE);
503 ErasePrompt();
504 DevSetColor(Color);
505 Int1 = 0;
506 }
507 }
508 }
509
510
511 void
RedrawPrompt()512 RedrawPrompt()
513
514 {
515 if (BackPrompt[0] == '\0') return;
516 DevSetColor(BackColor);
517 FBText(ROW_COLUMN,gi_numtextrows,1,BackPrompt);
518 Parameters.kpLastCursorColumn = 1 + strlen(BackPrompt);
519 }
520
521
522 void
AppendToOldPrompt(c)523 AppendToOldPrompt(c)
524
525 char c;
526 {
527 char s[4];
528
529 s[0] = ' ';
530 s[1] = s[0];
531 s[2] = c;
532 s[3] = '\0';
533 strcat(BackPrompt,s);
534 }
535
536
537 void
ErasePrompt()538 ErasePrompt()
539
540 {
541 OutlineText(1,gi_numtextrows,gi_numtextcols,
542 gi_numtextrows,FILL,ERASE,0);
543 Parameters.kpLastCursorColumn = 1;
544 BackPrompt[0] = '\0';
545 DevUpdate();
546 }
547
548
549 void
OutlineText(Left,Bottom,Right,Top,Type,DisplayOrErase,Pixel)550 OutlineText(Left,Bottom,Right,Top,Type,DisplayOrErase,Pixel)
551
552 int Left,Bottom,Right,Top,Pixel;
553 char Type,DisplayOrErase;
554 {
555 /*
556 * Outline the box defined by LeftColumn, BottomRow, RightColumn, and
557 * TopRow in the color associated with Pixel.
558 */
559
560 Bottom = gi_maxy-Bottom*gi_fntheight;
561 if (Bottom < 0) Bottom = 0;
562 Top = gi_maxy-(Top-1)*gi_fntheight;
563 if (Top > gi_maxy) Top = gi_maxy;
564 Left = (Left-1) * gi_fntwidth;
565 Right = (Right * gi_fntwidth) + 1;
566 if (Type == OUTLINE) {
567 ++Bottom;
568 --Top;
569 }
570 FBBox(Pixel,DisplayOrErase,Type,Left,Bottom,Right,Top-1);
571 }
572
573
574 /***********************************************************************
575 *
576 * Routines to dislay and erase viewports.
577 *
578 *
579 ***********************************************************************/
580
581
582 void
EraseLargeCoarseViewport()583 EraseLargeCoarseViewport()
584
585 {
586 FBEraseBox(View->kvLargeCoarseViewport->kaLeft-1,
587 View->kvLargeCoarseViewport->kaBottom-1,
588 View->kvLargeCoarseViewport->kaRight,
589 View->kvLargeCoarseViewport->kaTop);
590 }
591
592
593 void
EraseFineViewport()594 EraseFineViewport()
595
596 {
597 /*
598 * Erase fine positioning window in coarse window and patch
599 * up the hole. 'c' will disable showing of fine positioning
600 * window in Redisplay.
601 */
602 Parameters.kpRedisplayControl = COARSEVIEWPORTONLY;
603 EraseBox(View->kvFineWindow);
604 Redisplay(View->kvFineWindow);
605 Parameters.kpRedisplayControl = SPLITSCREEN;
606 }
607
608
609 void
ShowFineViewport()610 ShowFineViewport()
611
612 {
613 if (Parameters.kpRedisplayControl == COARSEVIEWPORTONLY) {
614 EraseLargeCoarseViewport();
615 Redisplay(View->kvCoarseWindow);
616 }
617 else {
618 FBEraseBox(View->kvFineViewport->kaLeft-1,
619 View->kvFineViewport->kaBottom-1,
620 View->kvFineViewport->kaRight,
621 View->kvFineViewport->kaTop);
622 /* Show fine positioning window in coarse window. */
623 ShowEmptyBox(HighlightingColor,View->kvFineWindow);
624 /* Redisplay in magnifying glass. */
625 Parameters.kpRedisplayControl = FINEVIEWPORTONLY;
626 Redisplay(View->kvFineWindow);
627 Parameters.kpRedisplayControl = SPLITSCREEN;
628 }
629 DevUpdate();
630 }
631
632
633 /***********************************************************************
634 *
635 * Routines to dislay and erase marked objects and points.
636 *
637 *
638 ***********************************************************************/
639
640
641 void
ShowCurrentObject(Pointer,DisplayOrErase)642 ShowCurrentObject(Pointer,DisplayOrErase)
643
644 struct o *Pointer;
645 char DisplayOrErase;
646 {
647 struct ka AOI;
648 static struct ks *ObjQ;
649 struct ks *q,*qq;
650
651 if (Pointer == NULL) {
652 for (q = ObjQ; q; q = qq) {
653 qq = q->ksSucc;
654 if (DisplayOrErase == DISPLAY)
655 mark_object(q->ksPointer);
656 else {
657 CDBB(Parameters.kpCellDesc,q->ksPointer,&AOI.kaLeft,
658 &AOI.kaBottom,&AOI.kaRight,&AOI.kaTop);
659 EraseBox(&AOI);
660 ObjQ = NULL;
661 Redisplay(&AOI);
662 tfree(q);
663 }
664 }
665 SetCurrentAOI(View->kvCoarseWindow);
666 DevUpdate();
667 return;
668 }
669
670 if (DisplayOrErase == DISPLAY) {
671 mark_object(Pointer);
672 q = alloc(ks);
673 if (q == NULL) MallocFailed();
674 q->ksPointer = Pointer;
675 q->ksSucc = ObjQ;
676 ObjQ = q;
677 }
678 else {
679 for (qq = NULL,q = ObjQ; q; qq = q,q = q->ksSucc)
680 if (q->ksPointer == Pointer) {
681 if (qq)
682 qq->ksSucc = q->ksSucc;
683 else
684 ObjQ = q->ksSucc;
685 tfree(q);
686 break;
687 }
688 CDBB(Parameters.kpCellDesc,Pointer,&AOI.kaLeft,&AOI.kaBottom,
689 &AOI.kaRight,&AOI.kaTop);
690 EraseBox(&AOI);
691 Redisplay(&AOI);
692 }
693 SetCurrentAOI(View->kvCoarseWindow);
694 DevUpdate();
695 }
696
697
698 static void
mark_object(Pointer)699 mark_object(Pointer)
700
701 struct o *Pointer;
702 {
703 struct ka AOI;
704 struct p *Path;
705 int Layer;
706 long Width;
707
708
709 if (Pointer->oType == CDWIRE) {
710 CDWire(Pointer,&Layer,&Width,&Path);
711 ShowWire(HighlightingColor,Width,Path);
712 }
713 else {
714 /*
715 * Show the object with an X through the bounding box.
716 */
717 CDBB(Parameters.kpCellDesc,Pointer,&AOI.kaLeft,&AOI.kaBottom,
718 &AOI.kaRight,&AOI.kaTop);
719 ShowLine(HighlightingColor,AOI.kaLeft,AOI.kaBottom,
720 AOI.kaRight,AOI.kaTop);
721 ShowLine(HighlightingColor,AOI.kaLeft,AOI.kaTop,
722 AOI.kaRight,AOI.kaBottom);
723 ShowEmptyBox(HighlightingColor,&AOI);
724 }
725 }
726
727
728 void
ShowMarker(DisplayOrErase,Color,X,Y,Delta,Type,Orient)729 ShowMarker(DisplayOrErase,Color,X,Y,Delta,Type,Orient)
730
731 char DisplayOrErase;
732 int Color;
733 long X,Y;
734 int Delta;
735 int Type;
736 int Orient;
737 {
738 struct t *TGen;
739 struct ka BB;
740 long X1,Y1,X2,Y2;
741 long DX, DY;
742
743 /* SRW ** save markers for redraw after screen alteration */
744 static struct mark *mlist;
745 struct mark *mm, *mtmp;
746
747 /* SRW ** display stored marks */
748 if (!Delta && DisplayOrErase == DISPLAY) {
749 for (mm = mlist; mm; mm = mm->next) {
750 show_mark(mm,Color);
751 }
752 ShowCurrentObject((struct o *)NULL,DISPLAY);
753 return;
754 }
755
756 /* SRW ** constant size on screen */
757 if (Parameters.kpRedisplayControl == COARSEVIEWPORTONLY)
758 Delta *= View->kvCoarseWindow->kaHeight/100;
759 else
760 Delta *= View->kvFineWindow->kaHeight/50;
761 Delta /= RESOLUTION;
762
763 if (DisplayOrErase == DISPLAY) {
764 DevSetColor(Color);
765
766 /* add marker to list */
767 mm = alloc(mark);
768 if (!mm) MallocFailed();
769 mm->X = X;
770 mm->Y = Y;
771 mm->Delta = Delta;
772 mm->Type = Type;
773 mm->Orient = Orient;
774 mm->next = mlist;
775 mlist = mm;
776
777 show_mark(mm,Color);
778 }
779 else {
780 /* remove from list */
781 for (mtmp = NULL,mm = mlist; mm; mtmp = mm,mm = mm->next) {
782 if (mm->X == X && mm->Y == Y) {
783 Delta = mm->Delta;
784 if (mm == mlist) mlist = mm->next;
785 else mtmp->next = mm->next;
786 tfree(mm);
787 break;
788 }
789 }
790 BB.kaLeft = X - Delta;
791 BB.kaRight = X + Delta;
792 BB.kaBottom = Y - Delta;
793 BB.kaTop = Y + Delta;
794 EraseBox(&BB);
795 Redisplay(&BB);
796 }
797 SetCurrentAOI(View->kvCoarseWindow);
798 }
799
800
801 static void
show_mark(m,Color)802 show_mark(m,Color)
803
804 struct mark *m;
805 int Color;
806 {
807 long X, Y;
808 int Delta;
809
810 X = m->X;
811 Y = m->Y;
812 Delta = m->Delta;
813
814 /* transform for PUSH */
815 TPoint(&X,&Y);
816
817 switch (m->Type) {
818 case MARK_ARROW:
819 switch (m->Orient) {
820 default:
821 case MARK_UP:
822 ShowLine(Color,X,Y-Delta,X,Y+Delta);
823 ShowLine(Color,X-Delta,Y,X,Y+Delta);
824 ShowLine(Color,X+Delta,Y,X,Y+Delta);
825 break;
826 case MARK_RT:
827 ShowLine(Color,X-Delta,Y,X+Delta,Y);
828 ShowLine(Color,X,Y+Delta,X+Delta,Y);
829 ShowLine(Color,X,Y-Delta,X+Delta,Y);
830 break;
831 case MARK_DN:
832 ShowLine(Color,X,Y-Delta,X,Y+Delta);
833 ShowLine(Color,X-Delta,Y,X,Y-Delta);
834 ShowLine(Color,X+Delta,Y,X,Y-Delta);
835 break;
836 case MARK_LT:
837 ShowLine(Color,X-Delta,Y,X+Delta,Y);
838 ShowLine(Color,X,Y+Delta,X-Delta,Y);
839 ShowLine(Color,X,Y-Delta,X-Delta,Y);
840 break;
841 }
842 break;
843 case MARK_CROSS:
844 /* cross (no orientation) */
845 ShowLine(Color,X-Delta,Y,X+Delta,Y);
846 ShowLine(Color,X,Y-Delta,X,Y+Delta);
847 break;
848 default:
849 /* graphical post-processor marks */
850 gp_mark(m->Type,Color,X,Y,Delta,m->Orient);
851 break;
852 }
853 }
854
855
856 static void
gp_mark(c,Color,x,y,delta,orient)857 gp_mark(c,Color,x,y,delta,orient)
858
859 int c, Color, x, y, delta, orient;
860 {
861 int x0, x1, y0, y1, y2;
862 struct ka AOI;
863
864 delta /= 2;
865 x0 = x - delta;
866 x1 = x + delta;
867 y0 = y - delta;
868 y1 = y;
869 y2 = y + delta;
870
871 AOI.kaLeft = x0;
872 AOI.kaRight = x1;
873 AOI.kaTop = y2;
874 AOI.kaBottom = y0;
875
876 switch (orient) {
877 case MARK_NONE:
878 EraseBox(&AOI);
879 ShowLine(Color,x0,y2,x1,y2);
880 ShowLine(Color,x1,y2,x1,y0);
881 ShowLine(Color,x1,y0,x0,y0);
882 ShowLine(Color,x0,y0,x0,y2);
883 break;
884 case MARK_UP: /* up */
885 AOI.kaTop += delta;
886 EraseBox(&AOI);
887 ShowLine(Color,x0,y2,(x0+x1)/2,y2+delta);
888 ShowLine(Color,(x0+x1)/2,y2+delta,x1,y2);
889 ShowLine(Color,x1,y2,x1,y0);
890 ShowLine(Color,x1,y0,x0,y0);
891 ShowLine(Color,x0,y0,x0,y2);
892 break;
893 case MARK_RT: /* right */
894 AOI.kaRight += delta;
895 EraseBox(&AOI);
896 ShowLine(Color,x0,y2,x1,y2);
897 ShowLine(Color,x1,y2,x1+delta,y1);
898 ShowLine(Color,x1+delta,y1,x1,y0);
899 ShowLine(Color,x1,y0,x0,y0);
900 ShowLine(Color,x0,y0,x0,y2);
901 break;
902 case MARK_DN: /* down */
903 AOI.kaBottom -= delta;
904 EraseBox(&AOI);
905 ShowLine(Color,x0,y2,x1,y2);
906 ShowLine(Color,x1,y2,x1,y0);
907 ShowLine(Color,x1,y0,(x0+x1)/2,y0-delta);
908 ShowLine(Color,(x0+x1)/2,y0-delta,x0,y0);
909 ShowLine(Color,x0,y0,x0,y2);
910 break;
911 case MARK_LT: /* left */
912 AOI.kaLeft -= delta;
913 EraseBox(&AOI);
914 ShowLine(Color,x0,y2,x1,y2);
915 ShowLine(Color,x1,y2,x1,y0);
916 ShowLine(Color,x1,y0,x0,y0);
917 ShowLine(Color,x0,y0,x0-delta,y1);
918 ShowLine(Color,x0-delta,y1,x0,y2);
919 break;
920 }
921
922 delta /= 2;
923 x0 += delta;
924 x1 -= delta;
925 y0 += delta;
926 y2 -= delta;
927
928 switch (c) {
929 case MARK_GP1:
930 ShowLine(Color,x1,y2,x1,y0);
931 break;
932 case MARK_GP2:
933 ShowLine(Color,x0,y2,x1,y2);
934 ShowLine(Color,x1,y2,x1,y1);
935 ShowLine(Color,x1,y1,x0,y1);
936 ShowLine(Color,x0,y1,x0,y0);
937 ShowLine(Color,x0,y0,x1,y0);
938 break;
939 case MARK_GP3:
940 ShowLine(Color,x1,y2,x1,y0);
941 ShowLine(Color,x0,y2,x1,y2);
942 ShowLine(Color,x0,y1,x1,y1);
943 ShowLine(Color,x0,y0,x1,y0);
944 break;
945 case MARK_GP4:
946 ShowLine(Color,x1,y2,x1,y0);
947 ShowLine(Color,x0,y2,x0,y1);
948 ShowLine(Color,x0,y1,x1,y1);
949 break;
950 case MARK_GP5:
951 ShowLine(Color,x1,y2,x0,y2);
952 ShowLine(Color,x0,y2,x0,y1);
953 ShowLine(Color,x0,y1,x1,y1);
954 ShowLine(Color,x1,y1,x1,y0);
955 ShowLine(Color,x1,y0,x0,y0);
956 break;
957 case MARK_GP6:
958 ShowLine(Color,x0,y2,x0,y0);
959 ShowLine(Color,x0,y1,x1,y1);
960 ShowLine(Color,x1,y1,x1,y0);
961 ShowLine(Color,x1,y0,x0,y0);
962 break;
963 case MARK_GP7:
964 ShowLine(Color,x0,y2,x1,y2);
965 ShowLine(Color,x1,y2,x1,y0);
966 break;
967 case MARK_GP8:
968 ShowLine(Color,x0,y2,x1,y2);
969 ShowLine(Color,x0,y1,x1,y1);
970 ShowLine(Color,x0,y0,x1,y0);
971 ShowLine(Color,x1,y2,x1,y0);
972 ShowLine(Color,x0,y2,x0,y0);
973 break;
974 }
975 }
976
977
978 /***********************************************************************
979 *
980 * Etc.
981 *
982 *
983 ***********************************************************************/
984
985 static int
my_strnicmp(s1,s2,n)986 my_strnicmp(s1,s2,n)
987
988 /* strnicmp function - many libraries lack this */
989 char *s1, *s2;
990 int n;
991 {
992 char c, d;
993
994 while (n--) {
995 c = *s1;
996 d = *s2;
997 if (c == '\0') return (-1);
998 if (d == '\0') return (1);
999 if (isupper(c)) c = tolower(c);
1000 if (isupper(d)) d = tolower(d);
1001 if (c != d) return (c-d);
1002 s1++;
1003 s2++;
1004 }
1005 return (0);
1006 }
1007
1008