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, &copy, 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