1 /*
2  * @(#)undodb.c	1.1	10/21/84
3  *
4  * Routines for recording (remembering) database activity to provide
5  * an undo capability for the SUN Gremlin picture editor.
6  *
7  * Mark Opperman (opcode@monet.BERKELEY)
8  *
9  */
10 
11 #include "gremlin.h"
12 
13 /* The following are used to point to the undo database lists */
14 
15 UNELT *unlist;
16 UNELT *unback;
17 
18 /* imports from point.c */
19 
20 POINT *PTMakePoint();
21 
22 /* imports from C */
23 
24 extern char *malloc();
25 extern char *strcpy();
26 
27 /* imports from db.c */
28 
29 extern DBClearElt();
30 
31 
32 /*
33  * This routine records an addition to the database by saving
34  * a pointer to the new element.
35  */
36 UNRembAdd(element, db)
37 ELT *element, *(*db);
38 {
39     register UNELT *temp;
40 
41     temp = (UNELT *) malloc(sizeof(UNELT));
42     temp->action = ADD;
43     temp->dbase  = db;
44     temp->oldelt = NULL;
45     temp->newelt = element;
46     temp->nextun = unlist;
47     unlist = temp;
48 }  /* end UNRembAdd */
49 
50 
51 /*
52  * This routine records a deletion from the database by saving
53  * a pointer to the deleted element.
54  */
55 UNRembDelete(element, db)
56 ELT *element, *(*db);
57 {
58     register UNELT *temp;
59 
60     temp = (UNELT *) malloc(sizeof(UNELT));
61     temp->action = DELETE;
62     temp->dbase  = db;
63     temp->oldelt = element;
64     temp->newelt = NULL;
65     temp->nextun = unlist;
66     unlist = temp;
67 }  /* end UNRembDelete */
68 
69 
70 /*
71  * This routine records a modification to the database.  The
72  * element passed to it is the element which will be modified and it
73  * is therefore copied (copying the text and pointlist also)
74  * and save as oldelt.  A pointer to the element which will be
75  * modified is saved in newelt.
76  */
77 UNRembMod(element, db)
78 ELT *element, *(*db);
79 {
80     register UNELT *temp;
81     register ELT *hold;
82     register POINT *pt;
83 
84     temp = (UNELT *) malloc(sizeof(UNELT));
85     temp->action = MOD;
86     temp->dbase = db;
87     temp->newelt = element;
88     temp->oldelt = hold = (ELT *) malloc(sizeof(ELT));
89     hold->type = element->type;
90     hold->brushf = element->brushf;
91     hold->size = element->size;
92     hold->textpt = malloc((unsigned) strlen(element->textpt) + 1);
93     (void) strcpy(hold->textpt, element->textpt);
94     pt = element->ptlist;
95     hold->ptlist = PTInit();
96 
97     while (!Nullpoint(pt)) {
98         (void) PTMakePoint(pt->x, pt->y, &(hold->ptlist));
99         pt = PTNextPoint(pt);
100     }
101 
102     temp->nextun = unlist;
103     unlist = temp;
104 }  /* end UNRembMod */
105 
106 
107 /*
108  * This routine clears the undo database.  The database is copied
109  * into the backup database and elements from the backup database
110  * are deleted and returned to free storage.  If nothing is in the undo
111  * database, the backup database is preserved.
112  */
113 UNForget()
114 {
115     register UNELT *temp;
116 
117     if (unlist == NULL)
118 	return;
119 
120     while (unback != NULL) {
121         temp = unback->nextun;
122         switch (unback->action) {
123 	    case ADD:
124 		free((char *) unback);
125                 break;
126 	    case MOD:
127 	    case DELETE:
128 		DBClearElt(unback->oldelt);
129                 free((char *) unback);
130                 break;
131         }
132         unback = temp;
133     }
134 
135     unback = unlist;
136     unlist = NULL;
137 }  /* end UNForget */
138