19ac52343Sopcode /*
2*b3593ea1Sopcode  * @(#)long2.c	1.2	01/03/85
39ac52343Sopcode  *
49ac52343Sopcode  * More routines to implement "long" commands for the SUN Gremlin
59ac52343Sopcode  * picture editor.
69ac52343Sopcode  *
79ac52343Sopcode  * Mark Opperman (opcode@monet.BERKELEY)
89ac52343Sopcode  *
99ac52343Sopcode  */
109ac52343Sopcode 
119ac52343Sopcode #include <suntool/tool_hs.h>
129ac52343Sopcode #include <suntool/menu.h>
139ac52343Sopcode #include <sys/file.h>
149ac52343Sopcode #include "gremlin.h"
159ac52343Sopcode #include <ctype.h>
169ac52343Sopcode 
179ac52343Sopcode /* imports from graphics files */
189ac52343Sopcode 
199ac52343Sopcode extern GRBlankPoints();
209ac52343Sopcode extern GRDisplayPoint();
219ac52343Sopcode extern GRSetTextPos();
229ac52343Sopcode 
239ac52343Sopcode /* imports from path.c */
249ac52343Sopcode 
259ac52343Sopcode extern PSetPath();
269ac52343Sopcode extern PConvertTilde();
279ac52343Sopcode extern char *PGetPath();
289ac52343Sopcode 
299ac52343Sopcode /* imports from display.c */
309ac52343Sopcode 
319ac52343Sopcode extern DISClearSetDisplay();
329ac52343Sopcode extern DISScreenAdd();
339ac52343Sopcode extern DISScreenErase();
349ac52343Sopcode 
359ac52343Sopcode /* imports from database files */
369ac52343Sopcode 
379ac52343Sopcode extern ELT *DBCopy();
389ac52343Sopcode extern ELT *DBRead();
399ac52343Sopcode extern ELT *DBCreateElt();
409ac52343Sopcode 
419ac52343Sopcode extern POINT *PTMakeTextPoints();
429ac52343Sopcode extern POINT *PTMakePoint();
439ac52343Sopcode 
449ac52343Sopcode extern DBAddSet();
459ac52343Sopcode extern DBChangeBrush();
469ac52343Sopcode extern DBChangeType();
479ac52343Sopcode extern DBChangeTypeStipple();
489ac52343Sopcode extern DBClearElt();
499ac52343Sopcode extern DBClearSet();
509ac52343Sopcode extern DBDelete();
519ac52343Sopcode extern DBGravitate();
529ac52343Sopcode extern DBXform();
539ac52343Sopcode 
549ac52343Sopcode /* imports from undodb.c */
559ac52343Sopcode 
569ac52343Sopcode extern UNELT *unlist;
579ac52343Sopcode extern UNELT *unback;
589ac52343Sopcode extern UNForget();
599ac52343Sopcode 
609ac52343Sopcode /* imports from short.c */
619ac52343Sopcode 
629ac52343Sopcode extern SHUpdate();
639ac52343Sopcode extern int adj[];
649ac52343Sopcode 
659ac52343Sopcode /* imports from text.c */
669ac52343Sopcode 
679ac52343Sopcode extern TxKillLine();
689ac52343Sopcode extern TxMsgOK();
699ac52343Sopcode extern TxPutMsg();
709ac52343Sopcode 
719ac52343Sopcode /* imports from menu.c  */
729ac52343Sopcode 
739ac52343Sopcode extern MNHighLt();
749ac52343Sopcode extern MNUnHighLt();
759ac52343Sopcode extern HiMode[];
769ac52343Sopcode 
779ac52343Sopcode /* imports from C */
789ac52343Sopcode 
799ac52343Sopcode extern char *strcpy();
809ac52343Sopcode extern char *sprintf();
819ac52343Sopcode extern char *malloc();
829ac52343Sopcode extern FILE *fopen();
839ac52343Sopcode 
849ac52343Sopcode /* imports from sun.c */
859ac52343Sopcode 
869ac52343Sopcode extern flush_window_input();
879ac52343Sopcode extern prompt_ok();
889ac52343Sopcode 
899ac52343Sopcode /* imports from main.c */
909ac52343Sopcode 
919ac52343Sopcode extern char namestripe[];
929ac52343Sopcode extern char version[];
939ac52343Sopcode extern struct tool *tool;
949ac52343Sopcode extern struct pixfont *text_pf;
959ac52343Sopcode 
969ac52343Sopcode extern tool_fd;
979ac52343Sopcode extern menu_fd;
989ac52343Sopcode 
999ac52343Sopcode extern ELT *PICTURE;                /* current PICTURE database      */
1009ac52343Sopcode extern ELT *cset;                   /* current set database          */
1019ac52343Sopcode extern Orientation;                 /* orientation of workspace      */
1029ac52343Sopcode extern SEARCH;                      /* flag for path search          */
1039ac52343Sopcode extern Alignment;                   /* point alignment indicator     */
1049ac52343Sopcode extern CBRUSH;			    /* current brush                 */
1059ac52343Sopcode extern CSTIPPLE;		    /* current stipple               */
1069ac52343Sopcode extern float PX, PY;                /* cursor coordinates            */
1079ac52343Sopcode extern float Lastx, Lasty;          /* previous cursor coordinates   */
1089ac52343Sopcode extern SEQ;                         /* point sequence number         */
1099ac52343Sopcode extern POINT *POINTLIST, *BACKPOINT;/* accumulated point list        */
1109ac52343Sopcode extern Gridsize;                    /* grid spacing                  */
1119ac52343Sopcode extern Adjustment;                  /* point adjustment mode         */
1129ac52343Sopcode extern CHANGED;                     /* PICTURE changed flag          */
1139ac52343Sopcode extern ELT *MEN[];                  /* pointers for user symbols     */
1149ac52343Sopcode extern POINT MENPOINT[];            /* pointers used fo user symbols */
1159ac52343Sopcode extern newfileformat;		    /* TRUE if using SUN file format */
1169ac52343Sopcode 
1179ac52343Sopcode /*  imports from long1.c         */
1189ac52343Sopcode 
1199ac52343Sopcode extern CSP();
1209ac52343Sopcode extern CP();
1219ac52343Sopcode 
1229ac52343Sopcode char *Editfile;
1239ac52343Sopcode char *eltnames[] = {
1249ac52343Sopcode     "BOTLEFT", "BOTRIGHT", "CENTCENT", "VECTOR", "ARC", "CURVE", "POLYGON",
1259ac52343Sopcode     "", "", "",
1269ac52343Sopcode     "TOPLEFT", "TOPCENT", "TOPRIGHT", "CENTLEFT", "CENTRIGHT", "BOTCENT"
1279ac52343Sopcode };
1289ac52343Sopcode 
129*b3593ea1Sopcode char nowrite_msg[] = "NO WRITE SINCE LAST CHANGE!       Press left button to \
130*b3593ea1Sopcode edit new file, middle or right button to cancel.";
131*b3593ea1Sopcode char filexists_msg[] = "FILE EXISTS!  Press left button to overwrite, middle \
132*b3593ea1Sopcode or right button to cancel.";
133*b3593ea1Sopcode static char quit_msg[] = "NO WRITE SINCE LAST CHANGE!       Press left button \
134*b3593ea1Sopcode to confirm quit, middle or right button to cancel.";
135*b3593ea1Sopcode static char quit2_msg[] = "Press left button to confirm quit, middle or right \
136*b3593ea1Sopcode button to cancel.";
1379ac52343Sopcode 
1389ac52343Sopcode #define BADNUM -1
1399ac52343Sopcode #define NONUM -2
1409ac52343Sopcode 
1419ac52343Sopcode static char badarg[] = "bad args";
1429ac52343Sopcode 
1439ac52343Sopcode 
1449ac52343Sopcode /*
1459ac52343Sopcode  * This routine creates and displays a POLYGON element from the
1469ac52343Sopcode  * points previously specified.
1479ac52343Sopcode  */
1489ac52343Sopcode static
LGDrawPolygon(bordered)1499ac52343Sopcode LGDrawPolygon(bordered)
1509ac52343Sopcode int bordered;
1519ac52343Sopcode {
1529ac52343Sopcode     register POINT *p1, *p2;
1539ac52343Sopcode     POINT *p0, *plist;
1549ac52343Sopcode     ELT *e1;
1559ac52343Sopcode     char *txt;
1569ac52343Sopcode 
1579ac52343Sopcode     if (SEQ < 3) {      /* not enough points */
1589ac52343Sopcode 	error("need at least 3 points");
1599ac52343Sopcode 	return;
1609ac52343Sopcode     }
1619ac52343Sopcode 
1629ac52343Sopcode     UNForget();
1639ac52343Sopcode 
1649ac52343Sopcode     DISClearSetDisplay();
1659ac52343Sopcode     DBClearSet();
1669ac52343Sopcode 
1679ac52343Sopcode     plist = PTInit();
1689ac52343Sopcode     p0 = p1 = POINTLIST;
1699ac52343Sopcode     (void) PTMakePoint(p1->x, p1->y, &plist);
1709ac52343Sopcode     p2 = PTNextPoint(p1);
1719ac52343Sopcode 
1729ac52343Sopcode     while (!Nullpoint(p2)) {
1739ac52343Sopcode 	(void) PTMakePoint(p2->x, p2->y, &plist);
1749ac52343Sopcode 	p1 = p2;
1759ac52343Sopcode 	p2 = PTNextPoint(p1);
1769ac52343Sopcode     }
1779ac52343Sopcode 
1789ac52343Sopcode     txt = malloc(1);
1799ac52343Sopcode     *txt = '\0';
1809ac52343Sopcode     e1 = DBCreateElt(POLYGON, plist, bordered ? CBRUSH : 0, CSTIPPLE,
1819ac52343Sopcode 								txt, &PICTURE);
1829ac52343Sopcode     DISScreenAdd(e1, pixmask | csetmask);
1839ac52343Sopcode     DBAddSet(e1);
1849ac52343Sopcode 
1859ac52343Sopcode     CP();
1869ac52343Sopcode     CHANGED = TRUE;
1879ac52343Sopcode }  /* end LGDrawPolygon */
1889ac52343Sopcode 
1899ac52343Sopcode 
LGBPolygon()1909ac52343Sopcode LGBPolygon()
1919ac52343Sopcode {
1929ac52343Sopcode     LGDrawPolygon(TRUE);
1939ac52343Sopcode }
1949ac52343Sopcode 
1959ac52343Sopcode 
LGPolygon()1969ac52343Sopcode LGPolygon()
1979ac52343Sopcode {
1989ac52343Sopcode     LGDrawPolygon(FALSE);
1999ac52343Sopcode }
2009ac52343Sopcode 
2019ac52343Sopcode 
2029ac52343Sopcode /*
2039ac52343Sopcode  * Modify elements in current set to POLYGON type with the indicated
2049ac52343Sopcode  * brush.  POLYGONs, CURVEs and VECTORs can be modified to either
2059ac52343Sopcode  * bordered or unbordered POLYGONs.
2069ac52343Sopcode  */
LGModifyPolygon(brush)2079ac52343Sopcode LGModifyPolygon(brush)
2089ac52343Sopcode int brush;		/* zero for unbordered */
2099ac52343Sopcode {
2109ac52343Sopcode     register ELT *elt;
2119ac52343Sopcode 
2129ac52343Sopcode     if (DBNullelt(cset)) {
2139ac52343Sopcode 	error("no current set");
2149ac52343Sopcode 	return;
2159ac52343Sopcode     }
2169ac52343Sopcode 
2179ac52343Sopcode     UNForget();
2189ac52343Sopcode     CSP();
2199ac52343Sopcode 
2209ac52343Sopcode     elt = cset;
2219ac52343Sopcode     while (!DBNullelt(elt)) {
2229ac52343Sopcode 	if (elt->type == POLYGON) {
2239ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
2249ac52343Sopcode 	    DBChangeBrush(elt, brush, &PICTURE);
2259ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
2269ac52343Sopcode 	}
2279ac52343Sopcode 	else if ((elt->type == VECTOR) || (elt->type == CURVE)) {
2289ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
2299ac52343Sopcode 	    if (brush != 0)			/* bordered polygon */
2309ac52343Sopcode 		DBChangeTypeStipple(elt, POLYGON, CSTIPPLE, &PICTURE);
2319ac52343Sopcode 	    else				/* unbordered polygon */
2329ac52343Sopcode 		DBChangeTypeBrushStipple(elt, POLYGON, 0, CSTIPPLE, &PICTURE);
2339ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
2349ac52343Sopcode 	}
2359ac52343Sopcode 
2369ac52343Sopcode 	elt = DBNextofSet(elt);
2379ac52343Sopcode     }
2389ac52343Sopcode 
2399ac52343Sopcode     CP();
2409ac52343Sopcode     CHANGED = TRUE;
2419ac52343Sopcode }  /* end LGModifyPolygon */
2429ac52343Sopcode 
2439ac52343Sopcode 
2449ac52343Sopcode /*
2459ac52343Sopcode  * Modify curves, vectors and polygons in the current set
2469ac52343Sopcode  * to bordered polygons.
2479ac52343Sopcode  */
LGMBPolygon()2489ac52343Sopcode LGMBPolygon()
2499ac52343Sopcode {
2509ac52343Sopcode     LGModifyPolygon(CBRUSH);
2519ac52343Sopcode }
2529ac52343Sopcode 
2539ac52343Sopcode 
2549ac52343Sopcode /*
2559ac52343Sopcode  * Modify curves, vectors and polygons in the current set
2569ac52343Sopcode  * to unbordered polygons.
2579ac52343Sopcode  */
LGMPolygon()2589ac52343Sopcode LGMPolygon()
2599ac52343Sopcode {
2609ac52343Sopcode     LGModifyPolygon(0);
2619ac52343Sopcode }
2629ac52343Sopcode 
2639ac52343Sopcode 
2649ac52343Sopcode /*
2659ac52343Sopcode  * Modify curves and polygons in the current set to vectors.
2669ac52343Sopcode  */
LGMVector()2679ac52343Sopcode LGMVector()
2689ac52343Sopcode {
2699ac52343Sopcode     register ELT *elt;
2709ac52343Sopcode 
2719ac52343Sopcode     if (DBNullelt(cset)) {
2729ac52343Sopcode 	error("no current set");
2739ac52343Sopcode 	return;
2749ac52343Sopcode     }
2759ac52343Sopcode 
2769ac52343Sopcode     UNForget();
2779ac52343Sopcode     CSP();
2789ac52343Sopcode 
2799ac52343Sopcode     elt = cset;
2809ac52343Sopcode     while (!DBNullelt(elt)) {
2819ac52343Sopcode 	if (elt->type == POLYGON) {
2829ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
2839ac52343Sopcode 	    if (elt->brushf != 0)
2849ac52343Sopcode 		DBChangeTypeStipple(elt, VECTOR, 0, &PICTURE);
2859ac52343Sopcode 	    else
2869ac52343Sopcode 		DBChangeTypeBrushStipple(elt, VECTOR, CBRUSH, 0, &PICTURE);
2879ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
2889ac52343Sopcode 	}
2899ac52343Sopcode 	else if (elt->type == CURVE) {
2909ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
2919ac52343Sopcode 	    DBChangeType(elt, VECTOR, &PICTURE);
2929ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
2939ac52343Sopcode 	}
2949ac52343Sopcode 	elt = DBNextofSet(elt);
2959ac52343Sopcode     }
2969ac52343Sopcode 
2979ac52343Sopcode     CP();
2989ac52343Sopcode     CHANGED = TRUE;
2999ac52343Sopcode }
3009ac52343Sopcode 
3019ac52343Sopcode 
3029ac52343Sopcode /*
3039ac52343Sopcode  * Modify vectors and polygons in the current set to curves.
3049ac52343Sopcode  */
LGMCurve()3059ac52343Sopcode LGMCurve()
3069ac52343Sopcode {
3079ac52343Sopcode     register ELT *elt;
3089ac52343Sopcode 
3099ac52343Sopcode     if (DBNullelt(cset)) {
3109ac52343Sopcode 	error("no current set");
3119ac52343Sopcode 	return;
3129ac52343Sopcode     }
3139ac52343Sopcode 
3149ac52343Sopcode     UNForget();
3159ac52343Sopcode     CSP();
3169ac52343Sopcode 
3179ac52343Sopcode     elt = cset;
3189ac52343Sopcode     while (!DBNullelt(elt)) {
3199ac52343Sopcode 	if (elt->type == VECTOR) {
3209ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
3219ac52343Sopcode 	    DBChangeType(elt, CURVE, &PICTURE);
3229ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
3239ac52343Sopcode 	}
3249ac52343Sopcode 	else if (elt->type == POLYGON) {
3259ac52343Sopcode 	    DISScreenErase(elt, pixmask | csetmask);
3269ac52343Sopcode 	    if (elt->brushf != 0)		/* bordered polygon */
3279ac52343Sopcode 		DBChangeTypeStipple(elt, CURVE, 0, &PICTURE);
3289ac52343Sopcode 	    else				/* unbordered polygon */
3299ac52343Sopcode 		DBChangeTypeBrushStipple(elt, CURVE, CBRUSH, 0, &PICTURE);
3309ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
3319ac52343Sopcode 	}
3329ac52343Sopcode 	elt = DBNextofSet(elt);
3339ac52343Sopcode     }
3349ac52343Sopcode 
3359ac52343Sopcode     CP();
3369ac52343Sopcode     CHANGED = TRUE;
3379ac52343Sopcode }
3389ac52343Sopcode 
3399ac52343Sopcode 
LGIncludeSet()3409ac52343Sopcode LGIncludeSet()
3419ac52343Sopcode /*
3429ac52343Sopcode  * This routine adds all elements selected by points in POINTLIST
3439ac52343Sopcode  * to the current set.  It does not remove previously selected elements.
3449ac52343Sopcode  */
3459ac52343Sopcode {
3469ac52343Sopcode     POINT *p1, *p2;
3479ac52343Sopcode     ELT *e1;
3489ac52343Sopcode     float n1, n2;
3499ac52343Sopcode 
3509ac52343Sopcode     if (DBNullelt(PICTURE))
3519ac52343Sopcode 	return;
3529ac52343Sopcode 
3539ac52343Sopcode     if (SEQ == 0) {	/* no points: entire picture becomes current set */
3549ac52343Sopcode         e1 = PICTURE;
3559ac52343Sopcode         while (!DBNullelt(e1)) {
3569ac52343Sopcode 	    if (!DBInCset(e1)) {		/* not now in current set */
3579ac52343Sopcode 		DBAddSet(e1);			/* add it to current set */
3589ac52343Sopcode 		DISScreenAdd(e1, csetmask);	/* and display it */
3599ac52343Sopcode 	    }
3609ac52343Sopcode             e1 = DBNextElt(e1);
3619ac52343Sopcode         }
3629ac52343Sopcode     }
3639ac52343Sopcode     else {
3649ac52343Sopcode         p1 = POINTLIST;
3659ac52343Sopcode 
3669ac52343Sopcode 	/* for each user point */
3679ac52343Sopcode         while (!Nullpoint(p1)) {
3689ac52343Sopcode 
3699ac52343Sopcode 	    /* find closest element */
3709ac52343Sopcode             DBGravitate(p1->x, p1->y, &n1, &n2, &p2, &e1, PICTURE, FALSE);
3719ac52343Sopcode 
3729ac52343Sopcode 	    /* if something's close and its not already in the current set */
3739ac52343Sopcode             if (!DBNullelt(e1) && !DBInCset(e1)) {
3749ac52343Sopcode                 DBAddSet(e1);				/* add it */
3759ac52343Sopcode                 DISScreenAdd(e1, csetmask);		/* and display it */
3769ac52343Sopcode             }
3779ac52343Sopcode             p1 = PTNextPoint(p1);
3789ac52343Sopcode         }
3799ac52343Sopcode     }
3809ac52343Sopcode 
3819ac52343Sopcode     CP();
3829ac52343Sopcode } /* end LGIncludeSet */
3839ac52343Sopcode 
3849ac52343Sopcode 
3859ac52343Sopcode /*
3869ac52343Sopcode  * This routine implements the menu command.  The contents of
3879ac52343Sopcode  * the specified user menu item is copied into the PICTURE transformed
3889ac52343Sopcode  * to the positioning point.
3899ac52343Sopcode  */
LGGet(buffer)3909ac52343Sopcode LGGet(buffer)
3919ac52343Sopcode int buffer;
3929ac52343Sopcode {
3939ac52343Sopcode 
3949ac52343Sopcode     ELT *elist, *e1;
3959ac52343Sopcode     POINT *plist;
3969ac52343Sopcode     int symbol, index;
3979ac52343Sopcode     float xmat[3][2];
3989ac52343Sopcode 
3999ac52343Sopcode     if (SEQ < 1) {
4009ac52343Sopcode         error("no positioning point");
4019ac52343Sopcode         return;
4029ac52343Sopcode     }
4039ac52343Sopcode 
4049ac52343Sopcode     UNForget();
4059ac52343Sopcode     buffer--;     /* users inputs number between 1 and N, actual
4069ac52343Sopcode                      buffer number is between 0 and N-1 */
4079ac52343Sopcode 
4089ac52343Sopcode     xmat[0][0] = xmat[1][1] = 1;    /* create transformation matrix */
4099ac52343Sopcode     xmat[0][1] = xmat[1][0] = 0;    /* for copy into PICTURE        */
4109ac52343Sopcode     plist = POINTLIST;
4119ac52343Sopcode 
4129ac52343Sopcode     while (!Nullpoint(plist)) {
4139ac52343Sopcode 	DISClearSetDisplay();
4149ac52343Sopcode         DBClearSet();
4159ac52343Sopcode         xmat[2][0] = plist->x - (MENPOINT[buffer]).x;
4169ac52343Sopcode         xmat[2][1] = plist->y - (MENPOINT[buffer]).y;
4179ac52343Sopcode         elist = MEN[buffer];
4189ac52343Sopcode 
4199ac52343Sopcode         while (!DBNullelt(elist)) { /* copy buffer to picture */
4209ac52343Sopcode             e1 = DBCopy(elist, xmat, &PICTURE);
4219ac52343Sopcode             DISScreenAdd(e1, pixmask | csetmask);
4229ac52343Sopcode             DBAddSet(e1);
4239ac52343Sopcode             elist = DBNextElt(elist);
4249ac52343Sopcode         }
4259ac52343Sopcode 
4269ac52343Sopcode         plist = PTNextPoint(plist);
4279ac52343Sopcode     }
4289ac52343Sopcode 
4299ac52343Sopcode     CP();
4309ac52343Sopcode     CHANGED = TRUE;
4319ac52343Sopcode }  /* end LGGet */
4329ac52343Sopcode 
4339ac52343Sopcode 
LGGet1()4349ac52343Sopcode LGGet1()
4359ac52343Sopcode {
4369ac52343Sopcode     LGGet(1);
4379ac52343Sopcode }
4389ac52343Sopcode 
4399ac52343Sopcode 
LGGet2()4409ac52343Sopcode LGGet2()
4419ac52343Sopcode {
4429ac52343Sopcode     LGGet(2);
4439ac52343Sopcode }
4449ac52343Sopcode 
4459ac52343Sopcode 
LGGet3()4469ac52343Sopcode LGGet3()
4479ac52343Sopcode {
4489ac52343Sopcode     LGGet(3);
4499ac52343Sopcode }
4509ac52343Sopcode 
4519ac52343Sopcode 
LGGet4()4529ac52343Sopcode LGGet4()
4539ac52343Sopcode {
4549ac52343Sopcode     LGGet(4);
4559ac52343Sopcode }
4569ac52343Sopcode 
4579ac52343Sopcode 
4589ac52343Sopcode /*
4599ac52343Sopcode  * This routine reads in the specified filename (command line) to the
4609ac52343Sopcode  * selected user symbol or current set if no user symbol is selected.  If
4619ac52343Sopcode  * no filename is specified, the current set is copied to the user symbol;
4629ac52343Sopcode  */
LGRead()4639ac52343Sopcode LGRead()
4649ac52343Sopcode {
4659ac52343Sopcode     POINT pos, ppos;
4669ac52343Sopcode     ELT *elist, *e1;
4679ac52343Sopcode     char tname[TEXT_BUFMAX];
4689ac52343Sopcode     float xmat[3][2];
4699ac52343Sopcode     int orient;
4709ac52343Sopcode 
4719ac52343Sopcode     text_getvalue(&tname[0]);
4729ac52343Sopcode     if (*tname == '\0') {
4739ac52343Sopcode         error("read from where?");
4749ac52343Sopcode         return;
4759ac52343Sopcode     }
4769ac52343Sopcode 
4779ac52343Sopcode     elist = DBRead(tname, &orient, &pos);	/* read file */
4789ac52343Sopcode     if (elist == (ELT *) NULL)
4799ac52343Sopcode 	return;
4809ac52343Sopcode 
4819ac52343Sopcode     UNForget();					/* forget changes registered */
4829ac52343Sopcode 						/* by DBRead */
4839ac52343Sopcode     if (SEQ < 1) {				/* no positioning point */
4849ac52343Sopcode         ppos.x = pos.x;
4859ac52343Sopcode         ppos.y = pos.y;
4869ac52343Sopcode     }
4879ac52343Sopcode     else {
4889ac52343Sopcode         ppos.x = POINTLIST->x;
4899ac52343Sopcode         ppos.y = POINTLIST->y;
4909ac52343Sopcode     }
4919ac52343Sopcode 
4929ac52343Sopcode     xmat[0][0] = xmat[1][1] = 1;		/* set up matrix to copy to */
4939ac52343Sopcode     xmat[0][1] = xmat[1][0] = 0;		/* appropriate place in */
4949ac52343Sopcode     xmat[2][0] = ppos.x - pos.x;		/* picture as current set */
4959ac52343Sopcode     xmat[2][1] = ppos.y - pos.y;
4969ac52343Sopcode     DISClearSetDisplay();
4979ac52343Sopcode     DBClearSet();
4989ac52343Sopcode 
4999ac52343Sopcode     while (!DBNullelt(elist)) {
5009ac52343Sopcode         e1 = DBCopy(elist, xmat, &PICTURE);
5019ac52343Sopcode         DISScreenAdd(e1, pixmask | csetmask);
5029ac52343Sopcode         DBAddSet(e1);
5039ac52343Sopcode         e1 = DBNextElt(elist);
5049ac52343Sopcode         DBClearElt(elist);
5059ac52343Sopcode         elist = e1;
5069ac52343Sopcode     }
5079ac52343Sopcode 
5089ac52343Sopcode     CHANGED = TRUE;
5099ac52343Sopcode     TxKillLine();
5109ac52343Sopcode     CP();
5119ac52343Sopcode }  /* end LGRead */
5129ac52343Sopcode 
5139ac52343Sopcode 
5149ac52343Sopcode /*
5159ac52343Sopcode  * This routine reads in a new PICTURE for editing
5169ac52343Sopcode  */
LGEdit()5179ac52343Sopcode LGEdit()
5189ac52343Sopcode {
5199ac52343Sopcode     FILE *fp, *POpen();
5209ac52343Sopcode     POINT pos;
5219ac52343Sopcode     ELT *e1;
5229ac52343Sopcode     char *prealname, *tn, tname[TEXT_BUFMAX];
5239ac52343Sopcode     int fd;
5249ac52343Sopcode 
5259ac52343Sopcode     text_getvalue(&tname[0]);
5269ac52343Sopcode 
5279ac52343Sopcode     if (CHANGED) {
5289ac52343Sopcode 	if (!prompt_ok(menu_fd, nowrite_msg)) {
5299ac52343Sopcode 	    return;
5309ac52343Sopcode 	}
5319ac52343Sopcode     }
5329ac52343Sopcode 
5339ac52343Sopcode     DISClearSetDisplay();
5349ac52343Sopcode     DBClearSet();
5359ac52343Sopcode 
5369ac52343Sopcode     while (!DBNullelt(PICTURE)) {	/* clear current PICTURE */
5379ac52343Sopcode         e1 = DBNextElt(PICTURE);
5389ac52343Sopcode         DBClearElt(PICTURE);
5399ac52343Sopcode         PICTURE = e1;
5409ac52343Sopcode     }
5419ac52343Sopcode 
5429ac52343Sopcode     tn = tname;
5439ac52343Sopcode 
5449ac52343Sopcode     POINTLIST = PTInit();		/* initialize globals */
5459ac52343Sopcode     SEQ = 0;
5469ac52343Sopcode     CHANGED = FALSE;
5479ac52343Sopcode     (void) strcpy(namestripe, version);
5489ac52343Sopcode 
5499ac52343Sopcode     if (*tname != '\0') {		/* filename present */
5509ac52343Sopcode         fp = POpen(tname, &prealname, SEARCH);
5519ac52343Sopcode 
5529ac52343Sopcode         if (fp == NULL) {
5539ac52343Sopcode             PICTURE = DBInit();
5549ac52343Sopcode 	    strcpy(Editfile, tname);
5559ac52343Sopcode 	    strcat(namestripe, tname);
5569ac52343Sopcode 	    error("creating new file");
5579ac52343Sopcode         }
5589ac52343Sopcode         else {
5599ac52343Sopcode 	    fclose(fp);
5609ac52343Sopcode 	    strcpy(Editfile, prealname);
5619ac52343Sopcode 	    strcat(namestripe, prealname);
5629ac52343Sopcode             PICTURE = DBRead(tname, &Orientation, &pos);
5639ac52343Sopcode 	    if ((fd = open(prealname, O_WRONLY | O_APPEND)) < 0)
5649ac52343Sopcode 		strcat(namestripe, " (read only)");
5659ac52343Sopcode 	    else
5669ac52343Sopcode 		close(fd);
5679ac52343Sopcode         }
5689ac52343Sopcode     }
5699ac52343Sopcode     else {				/* create new file */
5709ac52343Sopcode 	PICTURE = DBInit();
5719ac52343Sopcode 	(void) strcat(namestripe, "new file");
5729ac52343Sopcode 	(void) strcpy(Editfile, "");
5739ac52343Sopcode     }
5749ac52343Sopcode 
5759ac52343Sopcode     tool_display(tool);
5769ac52343Sopcode 
5779ac52343Sopcode     unlist = unback = NULL;
5789ac52343Sopcode     CP();
5799ac52343Sopcode     SHUpdate();      /* display new picture */
5809ac52343Sopcode     TxKillLine();
5819ac52343Sopcode }  /* end LGEdit */
5829ac52343Sopcode 
5839ac52343Sopcode 
5849ac52343Sopcode /*
5859ac52343Sopcode  * This routine (re) displays the points in the back-up pointlist
5869ac52343Sopcode  */
5879ac52343Sopcode static
restorepoints()5889ac52343Sopcode restorepoints()
5899ac52343Sopcode {
5909ac52343Sopcode 
5919ac52343Sopcode     register POINT *plist, *pl1;
5929ac52343Sopcode     register i;
5939ac52343Sopcode 
5949ac52343Sopcode     GRBlankPoints(POINTLIST);
5959ac52343Sopcode     plist = BACKPOINT;
5969ac52343Sopcode 
5979ac52343Sopcode     for (i=0; !Nullpoint(plist); ++i) {
5989ac52343Sopcode         Lastx = plist->x;
5999ac52343Sopcode         Lasty = plist->y;
6009ac52343Sopcode         GRDisplayPoint(plist->x, plist->y, i);
6019ac52343Sopcode         plist = PTNextPoint(plist);
6029ac52343Sopcode     }
6039ac52343Sopcode 
6049ac52343Sopcode     pl1 = POINTLIST;
6059ac52343Sopcode     POINTLIST = BACKPOINT;
6069ac52343Sopcode     SEQ = i;
6079ac52343Sopcode     BACKPOINT = pl1;
6089ac52343Sopcode }  /* end restorepoints */
6099ac52343Sopcode 
6109ac52343Sopcode 
6119ac52343Sopcode /*
6129ac52343Sopcode  * This routine uses the information in the undo database to reconstruct
6139ac52343Sopcode  * the PICTURE as it was before the last command.  The undo database is set
6149ac52343Sopcode  * so that the next undo would nullify this one.
6159ac52343Sopcode  * An undo of an Add is to delete the new element.
6169ac52343Sopcode  * Add the old element back to undo a delete.
6179ac52343Sopcode  * Modified elements are undone by copying the old element into the database
6189ac52343Sopcode  * in place of the modified element.
6199ac52343Sopcode  */
LGUndo()6209ac52343Sopcode LGUndo()
6219ac52343Sopcode {
6229ac52343Sopcode     UNELT *fix, *temp;
6239ac52343Sopcode     ELT *(*e1);
6249ac52343Sopcode 
6259ac52343Sopcode     fix = unlist;	/* initialize unlist so that undo-ing can */
6269ac52343Sopcode     unlist = NULL;	/* add items to properly undo the undo */
6279ac52343Sopcode 
6289ac52343Sopcode     if (fix == NULL) {
6299ac52343Sopcode         fix = unback;
6309ac52343Sopcode         unback = NULL;
6319ac52343Sopcode     }
6329ac52343Sopcode 
6339ac52343Sopcode     DISClearSetDisplay();
6349ac52343Sopcode     DBClearSet();
6359ac52343Sopcode 
6369ac52343Sopcode     while (fix != NULL) {
6379ac52343Sopcode         switch (fix->action) {
6389ac52343Sopcode 	    case ADD:
6399ac52343Sopcode 		DISScreenErase(fix->newelt, pixmask);
6409ac52343Sopcode                 TxMsgOK();
6419ac52343Sopcode                 restorepoints();
6429ac52343Sopcode                 DBDelete(fix->newelt, fix->dbase);
6439ac52343Sopcode                 temp = fix->nextun;
6449ac52343Sopcode                 free((char *) fix);
6459ac52343Sopcode                 fix = temp;
6469ac52343Sopcode                 break;
6479ac52343Sopcode 	    case DELETE:
6489ac52343Sopcode 		fix->action = ADD;   /* create undo unelt */
6499ac52343Sopcode                 fix->newelt = fix->oldelt;
6509ac52343Sopcode                 fix->oldelt = NULL;
6519ac52343Sopcode                 fix->newelt->nextelt = PICTURE;
6529ac52343Sopcode                 restorepoints();
6539ac52343Sopcode                 DISScreenAdd(fix->newelt, pixmask | csetmask);
6549ac52343Sopcode                 DBAddSet(fix->newelt);
6559ac52343Sopcode                 PICTURE = fix->newelt;    /* put in database */
6569ac52343Sopcode                 temp = fix->nextun;
6579ac52343Sopcode                 fix->nextun = unlist;     /* link into unlist */
6589ac52343Sopcode                 unlist = fix;
6599ac52343Sopcode                 fix = temp;
6609ac52343Sopcode                 break;
6619ac52343Sopcode 	    case MOD:
6629ac52343Sopcode 		DISScreenErase(fix->newelt, pixmask);
6639ac52343Sopcode                 TxMsgOK();
6649ac52343Sopcode                 restorepoints();
6659ac52343Sopcode                 DISScreenAdd(fix->oldelt, pixmask | csetmask);
6669ac52343Sopcode                 DBAddSet(fix->oldelt);
6679ac52343Sopcode                 e1 = fix->dbase;
6689ac52343Sopcode 
6699ac52343Sopcode                 while (*e1 != fix->newelt) { /* find elt to replace */
6709ac52343Sopcode                     e1 = &(DBNextElt((*e1)));
6719ac52343Sopcode                 }
6729ac52343Sopcode 
6739ac52343Sopcode                 fix->oldelt->nextelt = DBNextElt((*e1));
6749ac52343Sopcode                 *e1 = fix->oldelt;
6759ac52343Sopcode                 fix->oldelt = fix->newelt;
6769ac52343Sopcode                 fix->newelt = *e1;     /* create undo unelt */
6779ac52343Sopcode                 temp = fix->nextun;
6789ac52343Sopcode                 fix->nextun = unlist;
6799ac52343Sopcode                 unlist = fix;     /* link into unlist */
6809ac52343Sopcode                 fix = temp;
6819ac52343Sopcode                 break;
6829ac52343Sopcode         }
6839ac52343Sopcode     }
6849ac52343Sopcode }  /* end LGUndo */
6859ac52343Sopcode 
6869ac52343Sopcode 
6879ac52343Sopcode /*
6889ac52343Sopcode  * Write elements from elist to filename.
6899ac52343Sopcode  * If setonly is true, elements are taken from the "setnext"
6909ac52343Sopcode  * pointer; otherwise, elements are taken from "nextelt".
6919ac52343Sopcode  * Ie., the current set is written with setonly = TRUE and
6929ac52343Sopcode  * the complete picture is written with setonly = FALSE.
6939ac52343Sopcode  */
6949ac52343Sopcode static
LGWriteSet(elist,filename,setonly)6959ac52343Sopcode LGWriteSet(elist, filename, setonly)
6969ac52343Sopcode ELT *elist;
6979ac52343Sopcode char *filename;
6989ac52343Sopcode int setonly;
6999ac52343Sopcode {
7009ac52343Sopcode     FILE *fp;
7019ac52343Sopcode     POINT *plist, pos;
7029ac52343Sopcode     char string[256];
7039ac52343Sopcode 
7049ac52343Sopcode     fp = fopen(filename, "w");
7059ac52343Sopcode     if (fp == NULL) {
7069ac52343Sopcode         (void) sprintf(string, "can't open %s", filename);
7079ac52343Sopcode         error(string);
7089ac52343Sopcode         return;
7099ac52343Sopcode     }
7109ac52343Sopcode 
7119ac52343Sopcode     TxPutMsg("writing file...");
7129ac52343Sopcode     UNForget();
7139ac52343Sopcode     CHANGED = FALSE;
7149ac52343Sopcode 
7159ac52343Sopcode     if (SEQ > 0) {			/* specified a positioning point */
7169ac52343Sopcode         pos.x = POINTLIST->x;
7179ac52343Sopcode         pos.y = POINTLIST->y;
7189ac52343Sopcode     }
7199ac52343Sopcode     else {
7209ac52343Sopcode         if (!DBNullelt(elist)) {
7219ac52343Sopcode             pos.x = elist->ptlist->x;
7229ac52343Sopcode             pos.y = elist->ptlist->y;
7239ac52343Sopcode         }
7249ac52343Sopcode         else {
7259ac52343Sopcode             pos.x = pos.y = 0.0;
7269ac52343Sopcode         }
7279ac52343Sopcode     }
7289ac52343Sopcode 
7299ac52343Sopcode     if (newfileformat)
7309ac52343Sopcode 	fprintf(fp, "sungremlinfile\n");		/* write header */
7319ac52343Sopcode     else
7329ac52343Sopcode 	fprintf(fp, "gremlinfile\n");			/* write header */
7339ac52343Sopcode     fprintf(fp, "%d %1.2f %1.2f\n", Orientation, pos.x, pos.y);
7349ac52343Sopcode 
7359ac52343Sopcode     while (!DBNullelt(elist)) {			/* write each element */
7369ac52343Sopcode 	if (newfileformat)
7379ac52343Sopcode 	    fprintf(fp, "%s\n", eltnames[elist->type]);
7389ac52343Sopcode 	else
7399ac52343Sopcode 	    fprintf(fp, "%d\n", elist->type);
7409ac52343Sopcode 
7419ac52343Sopcode         plist = elist->ptlist;
7429ac52343Sopcode 
7439ac52343Sopcode         while (!Nullpoint(plist)) {		/* write each point */
7449ac52343Sopcode             fprintf(fp, "%1.2f %1.2f\n", plist->x, plist->y);
7459ac52343Sopcode             plist = PTNextPoint(plist);
7469ac52343Sopcode         }
7479ac52343Sopcode 
7489ac52343Sopcode 	if (newfileformat)
7499ac52343Sopcode 	    fprintf(fp, "*\n");			/* end pointlist */
7509ac52343Sopcode 	else
7519ac52343Sopcode 	    fprintf(fp, "-1.00 -1.00\n");	/* end pointlist */
7529ac52343Sopcode 
7539ac52343Sopcode         fprintf(fp, "%d %d\n", elist->brushf, elist->size);
7549ac52343Sopcode         fprintf(fp,"%d %s\n", strlen(elist->textpt), elist->textpt);
7559ac52343Sopcode         elist = setonly ? DBNextofSet(elist) : DBNextElt(elist);
7569ac52343Sopcode     }
7579ac52343Sopcode     fprintf(fp, "-1\n");
7589ac52343Sopcode 
7599ac52343Sopcode     (void) fclose(fp);
7609ac52343Sopcode     TxMsgOK();
7619ac52343Sopcode     TxKillLine();
7629ac52343Sopcode     CP();
7639ac52343Sopcode }  /* end LGWriteSet */
7649ac52343Sopcode 
7659ac52343Sopcode 
7669ac52343Sopcode /*
7679ac52343Sopcode  * This routine writes the current set into the specified filename
7689ac52343Sopcode  */
LGSave()7699ac52343Sopcode LGSave()
7709ac52343Sopcode {
7719ac52343Sopcode     FILE *fp;
7729ac52343Sopcode     char tname[TEXT_BUFMAX], filename[TEXT_BUFMAX], *tn, *fn;
7739ac52343Sopcode     int space, stat;
7749ac52343Sopcode 
7759ac52343Sopcode     space = TEXT_BUFMAX;
7769ac52343Sopcode     text_getvalue(&tname[0]);
7779ac52343Sopcode     tn = tname;
7789ac52343Sopcode     fn = filename;
7799ac52343Sopcode 
7809ac52343Sopcode     if (*tname == '\0') {
7819ac52343Sopcode         error("write to where?");
7829ac52343Sopcode         return;
7839ac52343Sopcode     }
7849ac52343Sopcode 
7859ac52343Sopcode     stat = PConvertTilde(&tn, &fn, &space);
7869ac52343Sopcode     *fn = '\0';
7879ac52343Sopcode 
7889ac52343Sopcode     if (stat == FALSE) {
7899ac52343Sopcode         sprintf(filename, "unknown path %s", tname);
7909ac52343Sopcode         error(filename);
7919ac52343Sopcode         return;
7929ac52343Sopcode     }
7939ac52343Sopcode 
7949ac52343Sopcode     fp = fopen(filename, "r");
7959ac52343Sopcode     if (fp != NULL) {
7969ac52343Sopcode 	 if (!prompt_ok(menu_fd, filexists_msg)) {
7979ac52343Sopcode 	    fclose(fp);
7989ac52343Sopcode 	    return;
7999ac52343Sopcode 	}
8009ac52343Sopcode 	else
8019ac52343Sopcode 	    fclose(fp);
8029ac52343Sopcode     }
8039ac52343Sopcode 
8049ac52343Sopcode     LGWriteSet(cset, filename, TRUE);
8059ac52343Sopcode }  /* end LGSave */;
8069ac52343Sopcode 
8079ac52343Sopcode 
8089ac52343Sopcode /*
8099ac52343Sopcode  * This routine writes the current PICTURE into the specified filename
8109ac52343Sopcode  * or to the current Editfile
8119ac52343Sopcode  */
LGWrite()8129ac52343Sopcode LGWrite()
8139ac52343Sopcode {
8149ac52343Sopcode     FILE *fp;
8159ac52343Sopcode     char tname[TEXT_BUFMAX], filename[TEXT_BUFMAX], *tn, *fn;
8169ac52343Sopcode     int space, stat;
8179ac52343Sopcode 
8189ac52343Sopcode     space = TEXT_BUFMAX;
8199ac52343Sopcode     text_getvalue(&tname[0]);
8209ac52343Sopcode     tn = tname;
8219ac52343Sopcode     fn = filename;
8229ac52343Sopcode 
8239ac52343Sopcode     if (tname[0] == '\0') {
8249ac52343Sopcode         if (Editfile[0] == '\0') {
8259ac52343Sopcode             error("write to where?");
8269ac52343Sopcode             return;
8279ac52343Sopcode         }
8289ac52343Sopcode 	strcpy(filename, Editfile);
8299ac52343Sopcode     }
8309ac52343Sopcode     else {
8319ac52343Sopcode 	stat = PConvertTilde(&tn, &fn, &space);
8329ac52343Sopcode 	*fn = '\0';
8339ac52343Sopcode 	if (stat == FALSE) {
8349ac52343Sopcode 	    sprintf(filename, "unknown path %s", tname);
8359ac52343Sopcode 	    error(filename);
8369ac52343Sopcode 	    return;
8379ac52343Sopcode 	}
8389ac52343Sopcode 	fp = fopen(filename, "r");
8399ac52343Sopcode 	if (fp != NULL) {
8409ac52343Sopcode 	    if (!prompt_ok(menu_fd, filexists_msg)) {
8419ac52343Sopcode 		fclose(fp);
8429ac52343Sopcode 		return;
8439ac52343Sopcode 	    }
8449ac52343Sopcode 	    else
8459ac52343Sopcode 		fclose(fp);
8469ac52343Sopcode 	}
8479ac52343Sopcode     }
8489ac52343Sopcode 
8499ac52343Sopcode     LGWriteSet(PICTURE, filename, FALSE);
8509ac52343Sopcode }  /* end LGWrite */;
8519ac52343Sopcode 
8529ac52343Sopcode 
8539ac52343Sopcode /*
8549ac52343Sopcode  * This routine terminates the editor.  The terminal states for the text
8559ac52343Sopcode  * terminal and the graphics display are restored and an EXIT is performed.
8569ac52343Sopcode  */
LGQuit()8579ac52343Sopcode LGQuit()
8589ac52343Sopcode {
8599ac52343Sopcode     if (prompt_ok(tool_fd, CHANGED ? quit_msg : quit2_msg))
8609ac52343Sopcode 	exit(0);
8619ac52343Sopcode }  /* end LGQuit */
8629ac52343Sopcode 
8639ac52343Sopcode 
8649ac52343Sopcode /*
8659ac52343Sopcode  * Horizontal Adjust -
8669ac52343Sopcode  * This routine toggles the adjustment mode.
8679ac52343Sopcode  */
LGHAdjust()8689ac52343Sopcode LGHAdjust()
8699ac52343Sopcode {
8709ac52343Sopcode     if (Adjustment == HORZ) {
8719ac52343Sopcode         MNUnHighLt(HiMode[adj[HORZ]]);
8729ac52343Sopcode         Adjustment = NOADJ;
8739ac52343Sopcode     }
8749ac52343Sopcode     else {
8759ac52343Sopcode 	if (Adjustment != NOADJ)
8769ac52343Sopcode 	    MNUnHighLt(HiMode[adj[Adjustment]]);
8779ac52343Sopcode         MNHighLt(HiMode[adj[HORZ]]);
8789ac52343Sopcode         Adjustment = HORZ;
8799ac52343Sopcode     }
8809ac52343Sopcode }  /* end LGHAdjust */
8819ac52343Sopcode 
8829ac52343Sopcode 
8839ac52343Sopcode /*
8849ac52343Sopcode  * Vertical Adjust -
8859ac52343Sopcode  * This routine toggles the adjustment mode.
8869ac52343Sopcode  */
LGVAdjust()8879ac52343Sopcode LGVAdjust()
8889ac52343Sopcode {
8899ac52343Sopcode     if (Adjustment == VERT) {
8909ac52343Sopcode         MNUnHighLt(HiMode[adj[VERT]]);
8919ac52343Sopcode         Adjustment = NOADJ;
8929ac52343Sopcode     }
8939ac52343Sopcode     else {
8949ac52343Sopcode 	if (Adjustment != NOADJ)
8959ac52343Sopcode 	    MNUnHighLt(HiMode[adj[Adjustment]]);
8969ac52343Sopcode         MNHighLt(HiMode[adj[VERT]]);
8979ac52343Sopcode         Adjustment = VERT;
8989ac52343Sopcode     }
8999ac52343Sopcode }  /* end LGVAdjust */
9009ac52343Sopcode 
9019ac52343Sopcode 
9029ac52343Sopcode /*
9039ac52343Sopcode  * This local routine returns 1 if x >= 0
9049ac52343Sopcode  * otherwise returns -1
9059ac52343Sopcode  */
9069ac52343Sopcode static
sign(x)9079ac52343Sopcode sign(x)
9089ac52343Sopcode float x;
9099ac52343Sopcode {
9109ac52343Sopcode     return((x >= 0) ? 1 : -1);
9119ac52343Sopcode }
9129ac52343Sopcode 
9139ac52343Sopcode 
9149ac52343Sopcode /*
9159ac52343Sopcode  * This routine is called by all mirroring routines to effect the
9169ac52343Sopcode  * transformation specified by xmat.
9179ac52343Sopcode  */
9189ac52343Sopcode static
mirror(xmat)9199ac52343Sopcode mirror(xmat)
9209ac52343Sopcode float xmat[3][2];
9219ac52343Sopcode {
9229ac52343Sopcode     register ELT *elt;
9239ac52343Sopcode     POINT pt, pos, *p1, *p2;
9249ac52343Sopcode     int i, j;
9259ac52343Sopcode 
9269ac52343Sopcode     UNForget();
9279ac52343Sopcode     elt = cset;
9289ac52343Sopcode     CSP();
9299ac52343Sopcode 
9309ac52343Sopcode     while (!DBNullelt(elt)) {
9319ac52343Sopcode         DISScreenErase(elt, pixmask | csetmask);
9329ac52343Sopcode         TxMsgOK();
9339ac52343Sopcode         DBXform(elt, xmat, &PICTURE);
9349ac52343Sopcode         if (TEXT(elt->type)) {
9359ac52343Sopcode 	    GRSetTextPos(elt->textpt, elt->type, elt->brushf, elt->size,
9369ac52343Sopcode 						    elt->ptlist, &pos);
9379ac52343Sopcode             elt->ptlist = PTMakeTextPoints(elt->textpt, elt->brushf, elt->size,
9389ac52343Sopcode 						    elt->ptlist, &pos);
9399ac52343Sopcode 	    DISScreenAdd(elt, pixmask | csetmask);
9409ac52343Sopcode         }
9419ac52343Sopcode         else {
9429ac52343Sopcode             if ((elt->type == ARC) && (elt->size > 0) &&
9439ac52343Sopcode 					(xmat[0][0] * xmat[1][1] < 0)) {
9449ac52343Sopcode 		/* arcs require special handling */
9459ac52343Sopcode                 /* but, circles OK and mirror in both directions OK */
9469ac52343Sopcode 	        /* otherwise, swap starting and ending points of arc */
9479ac52343Sopcode                 p1 = PTNextPoint(elt->ptlist);
9489ac52343Sopcode                 p2 = PTNextPoint(p1);
9499ac52343Sopcode                 pt.x = p1->x;
9509ac52343Sopcode                 pt.y = p1->y;
9519ac52343Sopcode                 p1->x = p2->x;
9529ac52343Sopcode                 p1->y = p2->y;
9539ac52343Sopcode                 p2->x = pt.x;
9549ac52343Sopcode                 p2->y = pt.y;
9559ac52343Sopcode 	    }
9569ac52343Sopcode             DISScreenAdd(elt, pixmask | csetmask);
9579ac52343Sopcode         }
9589ac52343Sopcode         elt = DBNextofSet(elt);
9599ac52343Sopcode     }
9609ac52343Sopcode     CP();
9619ac52343Sopcode }  /* end mirror */
9629ac52343Sopcode 
9639ac52343Sopcode 
9649ac52343Sopcode /*
9659ac52343Sopcode  * This routine mirrors the elements in the current set VERTICALLY
9669ac52343Sopcode  * The mirroring is accomplished by defining a transformation
9679ac52343Sopcode  * matrix and calling DBXform.
9689ac52343Sopcode  */
LGVMirror()9699ac52343Sopcode LGVMirror()
9709ac52343Sopcode {
9719ac52343Sopcode     float xmat[3][2];
9729ac52343Sopcode 
9739ac52343Sopcode     if (SEQ < 1) {      /* not enough points */
9749ac52343Sopcode         error("not enough points");
9759ac52343Sopcode         return;
9769ac52343Sopcode     }
9779ac52343Sopcode 
9789ac52343Sopcode     if (DBNullelt(cset)) {
9799ac52343Sopcode         error("no current set");
9809ac52343Sopcode         return;
9819ac52343Sopcode     }
9829ac52343Sopcode 
9839ac52343Sopcode     /* create transformation matrix to translate set to origin,
9849ac52343Sopcode        perform the mirroring and translate back */
9859ac52343Sopcode 
9869ac52343Sopcode     xmat[0][0] = -1.0;
9879ac52343Sopcode     xmat[1][1] = 1.0;
9889ac52343Sopcode     xmat[1][0] = xmat[0][1] = xmat[2][1] = 0.0;
9899ac52343Sopcode     xmat[2][0] = 2.0 * POINTLIST->x;
9909ac52343Sopcode 
9919ac52343Sopcode     mirror(xmat);
9929ac52343Sopcode     CHANGED = TRUE;
9939ac52343Sopcode }  /* end LGVMirror */
9949ac52343Sopcode 
9959ac52343Sopcode 
9969ac52343Sopcode /*
9979ac52343Sopcode  * This routine mirrors the elements in the current set HORIZONTALLY
9989ac52343Sopcode  * The mirroring is accomplished by defining a transformation
9999ac52343Sopcode  * matrix and calling DBXform.
10009ac52343Sopcode  */
LGHMirror()10019ac52343Sopcode LGHMirror()
10029ac52343Sopcode {
10039ac52343Sopcode     float xmat[3][2];
10049ac52343Sopcode 
10059ac52343Sopcode     if (SEQ < 1) {      /* not enough points */
10069ac52343Sopcode         error("not enough points");
10079ac52343Sopcode         return;
10089ac52343Sopcode     }
10099ac52343Sopcode 
10109ac52343Sopcode     if (DBNullelt(cset)) {
10119ac52343Sopcode         error("no current set");
10129ac52343Sopcode         return;
10139ac52343Sopcode     }
10149ac52343Sopcode 
10159ac52343Sopcode     /* create transformation matrix to translate set to origin,
10169ac52343Sopcode        perform the mirroring and translate back */
10179ac52343Sopcode 
10189ac52343Sopcode     xmat[0][0] = 1.0;
10199ac52343Sopcode     xmat[1][1] = -1.0;
10209ac52343Sopcode     xmat[1][0] = xmat[0][1] = xmat[2][0] = 0.0;
10219ac52343Sopcode     xmat[2][1] = 2.0 * POINTLIST->y;
10229ac52343Sopcode 
10239ac52343Sopcode     mirror(xmat);
10249ac52343Sopcode     CHANGED = TRUE;
10259ac52343Sopcode }  /* end LGHMirror */
10269ac52343Sopcode 
10279ac52343Sopcode 
10289ac52343Sopcode /*
10299ac52343Sopcode  * This routine looks at the command line for parameters to set
10309ac52343Sopcode  * the current search path.
10319ac52343Sopcode  */
LGPath()10329ac52343Sopcode LGPath()
10339ac52343Sopcode {
10349ac52343Sopcode     char buf[TEXT_BUFMAX];
10359ac52343Sopcode     char buf2[TEXT_BUFMAX];
10369ac52343Sopcode     register i, i2;
10379ac52343Sopcode 
10389ac52343Sopcode     i = i2 = -1;
10399ac52343Sopcode     text_getvalue(&buf[0]);
10409ac52343Sopcode     while (buf[++i]) {
10419ac52343Sopcode 	if (buf[i] != ' ')
10429ac52343Sopcode 	    buf2[++i2] = buf[i];
10439ac52343Sopcode     }
10449ac52343Sopcode     buf2[++i2] = '\0';
10459ac52343Sopcode 
10469ac52343Sopcode     if (*buf2 == '\0')
10479ac52343Sopcode 	TxPutMsg(PGetPath());     /* no arguments */
10489ac52343Sopcode     else {
10499ac52343Sopcode         SEARCH = TRUE;
10509ac52343Sopcode         PSetPath(buf2);
10519ac52343Sopcode     }
10529ac52343Sopcode 
10539ac52343Sopcode     TxKillLine();
10549ac52343Sopcode }  /* end LGPath */
10559ac52343Sopcode 
10569ac52343Sopcode 
1057*b3593ea1Sopcode /*
1058*b3593ea1Sopcode  * Sometimes it's important to do nothing.
1059*b3593ea1Sopcode  */
nop()10609ac52343Sopcode nop()
10619ac52343Sopcode {
10629ac52343Sopcode }
1063