1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 *
4 * This file is part of Geomview.
5 *
6 * Geomview is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Geomview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Geomview; see the file COPYING. If not, write
18 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19 * USA, or visit http://www.gnu.org.
20 */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30
31 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
32
33 #include "tlistP.h"
34 /*
35 * Tlist creation, editing and deletion
36 */
37
38 DEF_FREELIST(Tlist);
39
TlistFreeListPrune(void)40 void TlistFreeListPrune(void)
41 {
42 FreeListNode *old;
43 Tlist *oldtl;
44 size_t size = 0;
45
46 while (TlistFreeList) {
47 old = TlistFreeList;
48 TlistFreeList = old->next;
49 oldtl = (Tlist *)old;
50 if (oldtl->elements != NULL && oldtl->nallocated != 0) {
51 OOGLFree(oldtl->elements);
52 }
53 size += sizeof(Transform) * oldtl->nallocated;
54 OOGLFree(old);
55 size += sizeof(Tlist);
56 }
57 OOGLWarn("Freed %ld bytes.\n", size);
58 }
59
TlistDelete(Tlist * tlist)60 void TlistDelete(Tlist *tlist)
61 {
62 if(tlist) {
63 if (tlist->tlist != NULL) GeomDelete(tlist->tlist);
64 if (tlist->tlisthandle != NULL) HandlePDelete(&tlist->tlisthandle);
65 if (tlist->elements != NULL && tlist->freelisthead == NULL) {
66 OOGLFree(tlist->elements);
67 tlist->elements = NULL;
68 tlist->nallocated = 0;
69 }
70 }
71 }
72
TlistCopy(Tlist * t)73 Tlist *TlistCopy(Tlist *t)
74 {
75 Tlist *nt;
76 int i;
77
78 FREELIST_NEW(Tlist, nt);
79 GGeomInit(nt, t->Class, t->magic, NULL);
80 nt->freelisthead = &TlistFreeList;
81 nt->nelements = t->nelements;
82 if (nt->nallocated < nt->nelements) {
83 nt->elements =
84 OOGLRenewNE(Transform, nt->elements, nt->nelements, "Tlist transforms");
85 nt->nallocated = nt->nelements;
86 }
87 for (i = 0; i < nt->nelements; i++) {
88 TmCopy(t->elements[i], nt->elements[i]);
89 }
90 nt->tlist = GeomCopy(t->tlist);
91 nt->tlisthandle = NULL;
92 return(nt);
93
94 }
95
96 Geom *
TlistReplace(Tlist * tlist,Geom * geom)97 TlistReplace( Tlist *tlist, Geom *geom )
98 {
99 Geom *old;
100
101 if(tlist == NULL)
102 return NULL;
103
104 old = tlist->tlist;
105 tlist->tlist = geom;
106 return old;
107 }
108
109 int
TlistGet(Tlist * tlist,int attr,void * attrp)110 TlistGet( Tlist *tlist, int attr, void *attrp )
111 {
112 switch(attr) {
113 case CR_GEOM: *(Geom **)attrp = (Geom *)tlist->tlist; break;
114 default: return -1;
115 }
116 return 1;
117 }
118
119 Tlist *
TlistCreate(Tlist * exist,GeomClass * Classp,va_list * a_list)120 TlistCreate(Tlist *exist, GeomClass *Classp, va_list *a_list)
121 {
122 Tlist *tlist;
123 Geom *g;
124 Handle *h;
125 int copy = true;
126 bool copyel = false;
127 bool doinit = false;
128 int attr;
129 int i;
130 Transform *elements = NULL;
131
132 if (exist == NULL) {
133 FREELIST_NEW(Tlist, tlist);
134 GGeomInit (tlist, Classp, TLISTMAGIC, NULL);
135 tlist->freelisthead = &TlistFreeList;
136 tlist->tlisthandle = NULL;
137 tlist->tlist = NULL;
138 tlist->nelements = 0;
139 } else {
140 /* XXX Check that exist is a tlist. */
141 tlist = exist;
142 }
143
144 while ((attr = va_arg (*a_list, int))) switch(attr) {
145 case CR_GEOM:
146 case CR_TLIST:
147 h = NULL;
148 goto settlist;
149 case CR_HANDLE_GEOM:
150 h = va_arg(*a_list, Handle *);
151 settlist:
152 g = va_arg(*a_list, Geom *);
153 if(copy) {
154 RefIncr((Ref *)g);
155 }
156 if(tlist->tlist) {
157 GeomDelete(tlist->tlist);
158 }
159 tlist->tlist = g;
160 sethandle:
161 if(tlist->tlisthandle) {
162 HandleDelete(tlist->tlisthandle);
163 }
164 if(copy && h) {
165 RefIncr((Ref *)h);
166 }
167 tlist->tlisthandle = h;
168 break;
169 case CR_TLISTHANDLE:
170 h = va_arg(*a_list, Handle *);
171 goto sethandle;
172 case CR_ELEM:
173 elements = va_arg (*a_list, Transform *);
174 copyel = copy;
175 if (!copyel) {
176 OOGLFree(tlist->elements);
177 tlist->elements = NULL;
178 tlist->nallocated = 0;
179 }
180 if (elements == NULL) {
181 doinit = true;
182 }
183 break;
184 case CR_NELEM:
185 tlist->nelements = va_arg (*a_list, int);
186 doinit = true;
187 break;
188 default:
189 if(GeomDecorate(tlist, ©, attr, a_list)) {
190 OOGLError (0, "TlistCreate: undefined option: %d", attr);
191 if (exist == NULL) {
192 GeomDelete ((Geom *) tlist);
193 }
194 return NULL;
195 }
196 }
197
198 if (elements != NULL && !copyel) {
199 if (tlist->elements) {
200 OOGLFree(tlist->elements);
201 }
202 tlist->elements = elements;
203 tlist->nallocated = tlist->nelements;
204 } else {
205 if (tlist->nallocated < tlist->nelements) {
206 tlist->elements =
207 OOGLRenewNE(Transform, tlist->elements, tlist->nelements,
208 "TlistCreate: matrices");
209 tlist->nallocated = tlist->nelements;
210 }
211 if (elements == NULL) {
212 if (doinit) {
213 for (i = 0; i < tlist->nelements; i++) {
214 TmIdentity (tlist->elements[i] );
215 }
216 }
217 } else {
218 memcpy (tlist->elements, elements,
219 tlist->nelements * sizeof (Transform));
220 }
221 }
222
223 return tlist;
224 }
225