1 /* $Id: attrib.c,v 1.9 1997/07/24 01:24:28 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 2.4
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 /*
25 * $Log: attrib.c,v $
26 * Revision 1.9 1997/07/24 01:24:28 brianp
27 * changed precompiled header symbol from PCH to PC_HEADER
28 *
29 * Revision 1.8 1997/05/28 03:23:09 brianp
30 * added precompiled header (PCH) support
31 *
32 * Revision 1.7 1997/04/20 19:49:57 brianp
33 * replaced abort() calls with gl_problem()
34 *
35 * Revision 1.6 1997/04/01 04:18:28 brianp
36 * removed #include "draw.h"
37 *
38 * Revision 1.5 1997/01/28 22:13:02 brianp
39 * now there's separate state for CI and RGBA logic op enabled
40 *
41 * Revision 1.4 1996/10/01 03:30:01 brianp
42 * added #include "misc.h"
43 *
44 * Revision 1.3 1996/09/30 23:55:06 brianp
45 * call gl_DrawBuffer() when glPopAttrib(GL_COLOR_BUFFER_BIT)
46 *
47 * Revision 1.2 1996/09/27 01:24:14 brianp
48 * removed unused variables
49 *
50 * Revision 1.1 1996/09/13 01:38:16 brianp
51 * Initial revision
52 *
53 */
54
55
56 #ifdef PC_HEADER
57 #include "all.h"
58 #else
59 #include <stdlib.h>
60 #include <string.h>
61 #include "attrib.h"
62 #include "context.h"
63 #include "dlist.h"
64 #include "macros.h"
65 #include "misc.h"
66 #include "types.h"
67 #endif
68
69
70 #define MALLOC_STRUCT(T) (struct T *) malloc( sizeof(struct T) )
71
72
73
new_attrib_node(GLbitfield kind)74 static struct gl_attrib_node *new_attrib_node( GLbitfield kind )
75 {
76 struct gl_attrib_node *an;
77
78 an = (struct gl_attrib_node *) malloc( sizeof(struct gl_attrib_node) );
79 if (an) {
80 an->kind = kind;
81 }
82 return an;
83 }
84
85
86
gl_PushAttrib(GLcontext * ctx,GLbitfield mask)87 void gl_PushAttrib( GLcontext* ctx, GLbitfield mask )
88 {
89 struct gl_attrib_node *newnode;
90 struct gl_attrib_node *head;
91
92 if (INSIDE_BEGIN_END(ctx)) {
93 gl_error( ctx, GL_INVALID_OPERATION, "glPushAttrib" );
94 return;
95 }
96
97 if (ctx->AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) {
98 gl_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
99 return;
100 }
101
102 /* Build linked list of attribute nodes which save all attribute */
103 /* groups specified by the mask. */
104 head = NULL;
105
106 if (mask & GL_ACCUM_BUFFER_BIT) {
107 struct gl_accum_attrib *attr;
108
109 attr = MALLOC_STRUCT( gl_accum_attrib );
110 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
111 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
112 newnode->data = attr;
113 newnode->next = head;
114 head = newnode;
115 }
116
117 if (mask & GL_COLOR_BUFFER_BIT) {
118 struct gl_colorbuffer_attrib *attr;
119 attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
120 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
121 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
122 newnode->data = attr;
123 newnode->next = head;
124 head = newnode;
125 }
126
127 if (mask & GL_CURRENT_BIT) {
128 struct gl_current_attrib *attr;
129 attr = MALLOC_STRUCT( gl_current_attrib );
130 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
131 newnode = new_attrib_node( GL_CURRENT_BIT );
132 newnode->data = attr;
133 newnode->next = head;
134 head = newnode;
135 }
136
137 if (mask & GL_DEPTH_BUFFER_BIT) {
138 struct gl_depthbuffer_attrib *attr;
139 attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
140 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
141 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
142 newnode->data = attr;
143 newnode->next = head;
144 head = newnode;
145 }
146
147 if (mask & GL_ENABLE_BIT) {
148 struct gl_enable_attrib *attr;
149 GLuint i;
150 attr = MALLOC_STRUCT( gl_enable_attrib );
151 /* Copy enable flags from all other attributes into the enable struct. */
152 attr->AlphaTest = ctx->Color.AlphaEnabled;
153 attr->AutoNormal = ctx->Eval.AutoNormal;
154 attr->Blend = ctx->Color.BlendEnabled;
155 for (i=0;i<MAX_CLIP_PLANES;i++) {
156 attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i];
157 }
158 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
159 attr->CullFace = ctx->Polygon.CullFlag;
160 attr->DepthTest = ctx->Depth.Test;
161 attr->Dither = ctx->Color.DitherFlag;
162 attr->Fog = ctx->Fog.Enabled;
163 for (i=0;i<MAX_LIGHTS;i++) {
164 attr->Light[i] = ctx->Light.Light[i].Enabled;
165 }
166 attr->Lighting = ctx->Light.Enabled;
167 attr->LineSmooth = ctx->Line.SmoothFlag;
168 attr->LineStipple = ctx->Line.StippleFlag;
169 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
170 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
171 attr->Map1Color4 = ctx->Eval.Map1Color4;
172 attr->Map1Index = ctx->Eval.Map1Index;
173 attr->Map1Normal = ctx->Eval.Map1Normal;
174 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
175 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
176 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
177 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
178 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
179 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
180 attr->Map2Color4 = ctx->Eval.Map2Color4;
181 attr->Map2Index = ctx->Eval.Map2Index;
182 attr->Map2Normal = ctx->Eval.Map2Normal;
183 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
184 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
185 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
186 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
187 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
188 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
189 attr->Normalize = ctx->Transform.Normalize;
190 attr->PointSmooth = ctx->Point.SmoothFlag;
191 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
192 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
193 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
194 attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
195 attr->PolygonStipple = ctx->Polygon.StippleFlag;
196 attr->Scissor = ctx->Scissor.Enabled;
197 attr->Stencil = ctx->Stencil.Enabled;
198 attr->Texture = ctx->Texture.Enabled;
199 attr->TexGen = ctx->Texture.TexGenEnabled;
200 newnode = new_attrib_node( GL_ENABLE_BIT );
201 newnode->data = attr;
202 newnode->next = head;
203 head = newnode;
204 }
205
206 if (mask & GL_EVAL_BIT) {
207 struct gl_eval_attrib *attr;
208 attr = MALLOC_STRUCT( gl_eval_attrib );
209 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
210 newnode = new_attrib_node( GL_EVAL_BIT );
211 newnode->data = attr;
212 newnode->next = head;
213 head = newnode;
214 }
215
216 if (mask & GL_FOG_BIT) {
217 struct gl_fog_attrib *attr;
218 attr = MALLOC_STRUCT( gl_fog_attrib );
219 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
220 newnode = new_attrib_node( GL_FOG_BIT );
221 newnode->data = attr;
222 newnode->next = head;
223 head = newnode;
224 }
225
226 if (mask & GL_HINT_BIT) {
227 struct gl_hint_attrib *attr;
228 attr = MALLOC_STRUCT( gl_hint_attrib );
229 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
230 newnode = new_attrib_node( GL_HINT_BIT );
231 newnode->data = attr;
232 newnode->next = head;
233 head = newnode;
234 }
235
236 if (mask & GL_LIGHTING_BIT) {
237 struct gl_light_attrib *attr;
238 attr = MALLOC_STRUCT( gl_light_attrib );
239 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
240 newnode = new_attrib_node( GL_LIGHTING_BIT );
241 newnode->data = attr;
242 newnode->next = head;
243 head = newnode;
244 }
245
246 if (mask & GL_LINE_BIT) {
247 struct gl_line_attrib *attr;
248 attr = MALLOC_STRUCT( gl_line_attrib );
249 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
250 newnode = new_attrib_node( GL_LINE_BIT );
251 newnode->data = attr;
252 newnode->next = head;
253 head = newnode;
254 }
255
256 if (mask & GL_LIST_BIT) {
257 struct gl_list_attrib *attr;
258 attr = MALLOC_STRUCT( gl_list_attrib );
259 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
260 newnode = new_attrib_node( GL_LIST_BIT );
261 newnode->data = attr;
262 newnode->next = head;
263 head = newnode;
264 }
265
266 if (mask & GL_PIXEL_MODE_BIT) {
267 struct gl_pixel_attrib *attr;
268 attr = MALLOC_STRUCT( gl_pixel_attrib );
269 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
270 newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
271 newnode->data = attr;
272 newnode->next = head;
273 head = newnode;
274 }
275
276 if (mask & GL_POINT_BIT) {
277 struct gl_point_attrib *attr;
278 attr = MALLOC_STRUCT( gl_point_attrib );
279 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
280 newnode = new_attrib_node( GL_POINT_BIT );
281 newnode->data = attr;
282 newnode->next = head;
283 head = newnode;
284 }
285
286 if (mask & GL_POLYGON_BIT) {
287 struct gl_polygon_attrib *attr;
288 attr = MALLOC_STRUCT( gl_polygon_attrib );
289 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
290 newnode = new_attrib_node( GL_POLYGON_BIT );
291 newnode->data = attr;
292 newnode->next = head;
293 head = newnode;
294 }
295
296 if (mask & GL_POLYGON_STIPPLE_BIT) {
297 GLuint *stipple;
298 stipple = (GLuint *) malloc( 32*sizeof(GLuint) );
299 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
300 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
301 newnode->data = stipple;
302 newnode->next = head;
303 head = newnode;
304 }
305
306 if (mask & GL_SCISSOR_BIT) {
307 struct gl_scissor_attrib *attr;
308 attr = MALLOC_STRUCT( gl_scissor_attrib );
309 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
310 newnode = new_attrib_node( GL_SCISSOR_BIT );
311 newnode->data = attr;
312 newnode->next = head;
313 head = newnode;
314 }
315
316 if (mask & GL_STENCIL_BUFFER_BIT) {
317 struct gl_stencil_attrib *attr;
318 attr = MALLOC_STRUCT( gl_stencil_attrib );
319 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
320 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
321 newnode->data = attr;
322 newnode->next = head;
323 head = newnode;
324 }
325
326 if (mask & GL_TEXTURE_BIT) {
327 struct gl_texture_attrib *attr;
328 attr = MALLOC_STRUCT( gl_texture_attrib );
329 MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
330 newnode = new_attrib_node( GL_TEXTURE_BIT );
331 newnode->data = attr;
332 newnode->next = head;
333 head = newnode;
334 }
335
336 if (mask & GL_TRANSFORM_BIT) {
337 struct gl_transform_attrib *attr;
338 attr = MALLOC_STRUCT( gl_transform_attrib );
339 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
340 newnode = new_attrib_node( GL_TRANSFORM_BIT );
341 newnode->data = attr;
342 newnode->next = head;
343 head = newnode;
344 }
345
346 if (mask & GL_VIEWPORT_BIT) {
347 struct gl_viewport_attrib *attr;
348 attr = MALLOC_STRUCT( gl_viewport_attrib );
349 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
350 newnode = new_attrib_node( GL_VIEWPORT_BIT );
351 newnode->data = attr;
352 newnode->next = head;
353 head = newnode;
354 }
355
356 /* etc... */
357
358 ctx->AttribStack[ctx->AttribStackDepth] = head;
359 ctx->AttribStackDepth++;
360 }
361
362
363
gl_PopAttrib(GLcontext * ctx)364 void gl_PopAttrib( GLcontext* ctx )
365 {
366 struct gl_attrib_node *attr, *next;
367 struct gl_enable_attrib *enable;
368 GLuint i, oldDrawBuffer;
369
370 if (INSIDE_BEGIN_END(ctx)) {
371 gl_error( ctx, GL_INVALID_OPERATION, "glPopAttrib" );
372 return;
373 }
374
375 if (ctx->AttribStackDepth==0) {
376 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
377 return;
378 }
379
380 ctx->AttribStackDepth--;
381 attr = ctx->AttribStack[ctx->AttribStackDepth];
382
383 while (attr) {
384 switch (attr->kind) {
385 case GL_ACCUM_BUFFER_BIT:
386 MEMCPY( &ctx->Accum, attr->data, sizeof(struct gl_accum_attrib) );
387 break;
388 case GL_COLOR_BUFFER_BIT:
389 oldDrawBuffer = ctx->Color.DrawBuffer;
390 MEMCPY( &ctx->Color, attr->data,
391 sizeof(struct gl_colorbuffer_attrib) );
392 if (ctx->Color.DrawBuffer != oldDrawBuffer) {
393 gl_DrawBuffer(ctx, ctx->Color.DrawBuffer);
394 }
395 break;
396 case GL_CURRENT_BIT:
397 MEMCPY( &ctx->Current, attr->data,
398 sizeof(struct gl_current_attrib) );
399 break;
400 case GL_DEPTH_BUFFER_BIT:
401 MEMCPY( &ctx->Depth, attr->data,
402 sizeof(struct gl_depthbuffer_attrib) );
403 break;
404 case GL_ENABLE_BIT:
405 enable = (struct gl_enable_attrib *) attr->data;
406 ctx->Color.AlphaEnabled = enable->AlphaTest;
407 ctx->Transform.Normalize = enable->AutoNormal;
408 ctx->Color.BlendEnabled = enable->Blend;
409 for (i=0;i<MAX_CLIP_PLANES;i++) {
410 ctx->Transform.ClipEnabled[i] = enable->ClipPlane[i];
411 }
412 ctx->Light.ColorMaterialEnabled = enable->ColorMaterial;
413 ctx->Polygon.CullFlag = enable->CullFace;
414 ctx->Depth.Test = enable->DepthTest;
415 ctx->Color.DitherFlag = enable->Dither;
416 ctx->Fog.Enabled = enable->Fog;
417 ctx->Light.Enabled = enable->Lighting;
418 ctx->Line.SmoothFlag = enable->LineSmooth;
419 ctx->Line.StippleFlag = enable->LineStipple;
420 ctx->Color.IndexLogicOpEnabled = enable->IndexLogicOp;
421 ctx->Color.ColorLogicOpEnabled = enable->ColorLogicOp;
422 ctx->Eval.Map1Color4 = enable->Map1Color4;
423 ctx->Eval.Map1Index = enable->Map1Index;
424 ctx->Eval.Map1Normal = enable->Map1Normal;
425 ctx->Eval.Map1TextureCoord1 = enable->Map1TextureCoord1;
426 ctx->Eval.Map1TextureCoord2 = enable->Map1TextureCoord2;
427 ctx->Eval.Map1TextureCoord3 = enable->Map1TextureCoord3;
428 ctx->Eval.Map1TextureCoord4 = enable->Map1TextureCoord4;
429 ctx->Eval.Map1Vertex3 = enable->Map1Vertex3;
430 ctx->Eval.Map1Vertex4 = enable->Map1Vertex4;
431 ctx->Eval.Map2Color4 = enable->Map2Color4;
432 ctx->Eval.Map2Index = enable->Map2Index;
433 ctx->Eval.Map2Normal = enable->Map2Normal;
434 ctx->Eval.Map2TextureCoord1 = enable->Map2TextureCoord1;
435 ctx->Eval.Map2TextureCoord2 = enable->Map2TextureCoord2;
436 ctx->Eval.Map2TextureCoord3 = enable->Map2TextureCoord3;
437 ctx->Eval.Map2TextureCoord4 = enable->Map2TextureCoord4;
438 ctx->Eval.Map2Vertex3 = enable->Map2Vertex3;
439 ctx->Eval.Map2Vertex4 = enable->Map2Vertex4;
440 ctx->Transform.Normalize = enable->Normalize;
441 ctx->Point.SmoothFlag = enable->PointSmooth;
442 ctx->Polygon.OffsetPoint = enable->PolygonOffsetPoint;
443 ctx->Polygon.OffsetLine = enable->PolygonOffsetLine;
444 ctx->Polygon.OffsetFill = enable->PolygonOffsetFill;
445 ctx->Polygon.OffsetAny = ctx->Polygon.OffsetPoint ||
446 ctx->Polygon.OffsetLine ||
447 ctx->Polygon.OffsetFill;
448 ctx->Polygon.SmoothFlag = enable->PolygonSmooth;
449 ctx->Polygon.StippleFlag = enable->PolygonStipple;
450 ctx->Scissor.Enabled = enable->Scissor;
451 ctx->Stencil.Enabled = enable->Stencil;
452 ctx->Texture.Enabled = enable->Texture;
453 ctx->Texture.TexGenEnabled = enable->TexGen;
454 break;
455 case GL_EVAL_BIT:
456 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
457 break;
458 case GL_FOG_BIT:
459 MEMCPY( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) );
460 break;
461 case GL_HINT_BIT:
462 MEMCPY( &ctx->Hint, attr->data, sizeof(struct gl_hint_attrib) );
463 break;
464 case GL_LIGHTING_BIT:
465 MEMCPY( &ctx->Light, attr->data, sizeof(struct gl_light_attrib) );
466 break;
467 case GL_LINE_BIT:
468 MEMCPY( &ctx->Line, attr->data, sizeof(struct gl_line_attrib) );
469 break;
470 case GL_LIST_BIT:
471 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
472 break;
473 case GL_PIXEL_MODE_BIT:
474 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
475 break;
476 case GL_POINT_BIT:
477 MEMCPY( &ctx->Point, attr->data, sizeof(struct gl_point_attrib) );
478 break;
479 case GL_POLYGON_BIT:
480 MEMCPY( &ctx->Polygon, attr->data,
481 sizeof(struct gl_polygon_attrib) );
482 break;
483 case GL_POLYGON_STIPPLE_BIT:
484 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
485 break;
486 case GL_SCISSOR_BIT:
487 MEMCPY( &ctx->Scissor, attr->data,
488 sizeof(struct gl_scissor_attrib) );
489 break;
490 case GL_STENCIL_BUFFER_BIT:
491 MEMCPY( &ctx->Stencil, attr->data,
492 sizeof(struct gl_stencil_attrib) );
493 break;
494 case GL_TRANSFORM_BIT:
495 MEMCPY( &ctx->Transform, attr->data,
496 sizeof(struct gl_transform_attrib) );
497 break;
498 case GL_TEXTURE_BIT:
499 MEMCPY( &ctx->Texture, attr->data,
500 sizeof(struct gl_texture_attrib) );
501 break;
502 case GL_VIEWPORT_BIT:
503 MEMCPY( &ctx->Viewport, attr->data,
504 sizeof(struct gl_viewport_attrib) );
505 break;
506 default:
507 gl_problem( ctx, "Bad attrib flag in PopAttrib");
508 break;
509 }
510
511 next = attr->next;
512 free( (void *) attr->data );
513 free( (void *) attr );
514 attr = next;
515 }
516
517 ctx->NewState = NEW_ALL;
518 }
519
520
521 #define GL_CLIENT_PACK_BIT (1<<20)
522 #define GL_CLIENT_UNPACK_BIT (1<<21)
523
524
gl_PushClientAttrib(GLcontext * ctx,GLbitfield mask)525 void gl_PushClientAttrib( GLcontext *ctx, GLbitfield mask )
526 {
527 struct gl_attrib_node *newnode;
528 struct gl_attrib_node *head;
529
530 if (INSIDE_BEGIN_END(ctx)) {
531 gl_error( ctx, GL_INVALID_OPERATION, "glPushClientAttrib" );
532 return;
533 }
534
535 if (ctx->ClientAttribStackDepth>=MAX_CLIENT_ATTRIB_STACK_DEPTH) {
536 gl_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
537 return;
538 }
539
540 /* Build linked list of attribute nodes which save all attribute */
541 /* groups specified by the mask. */
542 head = NULL;
543
544 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
545 struct gl_pixelstore_attrib *attr;
546 /* packing attribs */
547 attr = MALLOC_STRUCT( gl_pixelstore_attrib );
548 MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
549 newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
550 newnode->data = attr;
551 newnode->next = head;
552 head = newnode;
553 /* unpacking attribs */
554 attr = MALLOC_STRUCT( gl_pixelstore_attrib );
555 MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) );
556 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
557 newnode->data = attr;
558 newnode->next = head;
559 head = newnode;
560 }
561 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
562 struct gl_array_attrib *attr;
563 attr = MALLOC_STRUCT( gl_array_attrib );
564 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
565 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
566 newnode->data = attr;
567 newnode->next = head;
568 head = newnode;
569 }
570
571 /* etc... */
572
573 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
574 ctx->ClientAttribStackDepth++;
575 }
576
577
578
579
gl_PopClientAttrib(GLcontext * ctx)580 void gl_PopClientAttrib( GLcontext *ctx )
581 {
582 struct gl_attrib_node *attr, *next;
583
584 if (INSIDE_BEGIN_END(ctx)) {
585 gl_error( ctx, GL_INVALID_OPERATION, "glPopClientAttrib" );
586 return;
587 }
588
589 if (ctx->ClientAttribStackDepth==0) {
590 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
591 return;
592 }
593
594 ctx->ClientAttribStackDepth--;
595 attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
596
597 while (attr) {
598 switch (attr->kind) {
599 case GL_CLIENT_PACK_BIT:
600 MEMCPY( &ctx->Pack, attr->data,
601 sizeof(struct gl_pixelstore_attrib) );
602 break;
603 case GL_CLIENT_UNPACK_BIT:
604 MEMCPY( &ctx->Unpack, attr->data,
605 sizeof(struct gl_pixelstore_attrib) );
606 break;
607 case GL_CLIENT_VERTEX_ARRAY_BIT:
608 MEMCPY( &ctx->Array, attr->data,
609 sizeof(struct gl_array_attrib) );
610 break;
611 default:
612 gl_problem( ctx, "Bad attrib flag in PopClientAttrib");
613 break;
614 }
615
616 next = attr->next;
617 free( (void *) attr->data );
618 free( (void *) attr );
619 attr = next;
620 }
621
622 ctx->NewState = NEW_ALL;
623 }
624
625