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 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 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 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 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 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