| 1 | /*********************************************************************** |
| 2 | |
| 3 | FONCTION : |
| 4 | ---------- |
| 5 | File OpenGl_togl_texture.c : |
| 6 | |
| 7 | |
| 8 | REMARQUES: |
| 9 | ---------- |
| 10 | |
| 11 | |
| 12 | HISTORIQUE DES MODIFICATIONS : |
| 13 | -------------------------------- |
| 14 | 05-08-97 : PCT ; Support texture mapping |
| 15 | ajout pour deuxieme passe du texture mapping |
| 16 | |
| 17 | ************************************************************************/ |
| 18 | |
| 19 | #define G003 /* EUG 16-09-99 ZBufferAuto treatment |
| 20 | */ |
| 21 | |
| 22 | /*----------------------------------------------------------------------*/ |
| 23 | /* |
| 24 | * Includes |
| 25 | */ |
| 26 | |
| 27 | #include <OpenGl_tgl_all.hxx> |
| 28 | |
| 29 | #include <stddef.h> |
| 30 | #include <stdio.h> |
| 31 | |
| 32 | #include <OpenGl_cmn_varargs.hxx> |
| 33 | #include <OpenGl_tsm.hxx> |
| 34 | #include <OpenGl_tsm_ws.hxx> |
| 35 | #include <OpenGl_Memory.hxx> |
| 36 | |
| 37 | static MtblPtr TsmMtblArray[TelLast]; |
| 38 | |
| 39 | /* Fixed Header info for a structure */ |
| 40 | struct TSM_HEAD_STRUCT |
| 41 | { |
| 42 | Tint num; /* number of elements present */ |
| 43 | }; |
| 44 | typedef TSM_HEAD_STRUCT TSM_HEAD; |
| 45 | typedef TSM_HEAD_STRUCT* tsm_head; |
| 46 | |
| 47 | /* The head of the list when the structure is in the form of a list */ |
| 48 | struct TSM_LHEAD_STRUCT |
| 49 | { |
| 50 | tsm_node next; // first list node |
| 51 | tsm_node prev; // last list node for reverse iteration |
| 52 | TSM_HEAD header; |
| 53 | }; |
| 54 | typedef TSM_LHEAD_STRUCT TSM_LHEAD; |
| 55 | typedef TSM_LHEAD_STRUCT *tsm_lhead; |
| 56 | |
| 57 | /* A Structure having fixed header and variable list of elements */ |
| 58 | struct TSM_STRUCT_STRUCT |
| 59 | { |
| 60 | TSM_LHEAD elemListHead; |
| 61 | IMPLEMENT_MEMORY_OPERATORS |
| 62 | }; |
| 63 | typedef TSM_STRUCT_STRUCT TSM_STRUCT; |
| 64 | typedef TSM_STRUCT_STRUCT *tsm_struct; |
| 65 | |
| 66 | #define TsmStructureNotOpen -1 |
| 67 | #define TsmInvalidStructure -1 |
| 68 | |
| 69 | /* Context maintained for the currently open structure */ |
| 70 | struct TSM_CONTEXT_STRUCT |
| 71 | { |
| 72 | Tint stid; /* Current Open Structure */ |
| 73 | Tint ind; /* Current Element Index */ |
| 74 | /* = TsmStructureNotOpen if no structure currently open */ |
| 75 | tsm_struct s; /* Current Structure Pointer */ |
| 76 | tsm_node n; /* Current Element list node */ |
| 77 | }; |
| 78 | typedef TSM_CONTEXT_STRUCT TSM_CONTEXT; |
| 79 | typedef TSM_CONTEXT_STRUCT* tsm_context; |
| 80 | |
| 81 | static TSM_CONTEXT context = { TsmInvalidStructure, TsmStructureNotOpen, 0, 0 }; |
| 82 | |
| 83 | static TEditMode edit_mode; |
| 84 | |
| 85 | #define TSM_HTBL_SIZE 251 |
| 86 | typedef NCollection_List<TSM_NODE*> NodeList; |
| 87 | typedef NCollection_DataMap<Tint, TSM_STRUCT*> StructMap; |
| 88 | Handle(NCollection_BaseAllocator) _Allocator = NCollection_BaseAllocator::CommonBaseAllocator(); |
| 89 | static StructMap _StructMap( 1, _Allocator ); |
| 90 | |
| 91 | |
| 92 | |
| 93 | /* Global workstation variable */ |
| 94 | Tint TglActiveWs; /* valid only during traversals */ |
| 95 | |
| 96 | void |
| 97 | TsmInitAllClasses( MtblPtr (**tbl)(TelType*), Tint size ) |
| 98 | { |
| 99 | register Tint i; |
| 100 | TelType el; |
| 101 | register MtblPtr fp; |
| 102 | |
| 103 | for( i=0; i<size; i++ ) |
| 104 | { |
| 105 | fp = tbl[i](&el); |
| 106 | TsmMtblArray[el] = fp; |
| 107 | } |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | /* This function invokes the required method of the element type by looking |
| 112 | up an array of Method Tables of each element. |
| 113 | The arguments passed to the method are the data of the element and any |
| 114 | other data that needs to be sent. |
| 115 | In the case of ADD_TO_STRUCTURE methods, data should be the address of the |
| 116 | element data. Other wise, it is the element data itself |
| 117 | */ |
| 118 | |
| 119 | TStatus |
| 120 | TsmSendMessage( TelType el, TMsgType msg, TSM_ELEM_DATA data, Tint n, ... ) |
| 121 | { |
| 122 | #if defined (SOLARIS) || defined (IRIXO32) |
| 123 | cmn_key *k; |
| 124 | #else |
| 125 | cmn_key k[TMaxArgs]; |
| 126 | |
| 127 | // Nullifies 0-th element of the "k" array |
| 128 | // because it might be used in a UserDraw function |
| 129 | // to get information on view ID, for example. |
| 130 | k[0] = NULL; |
| 131 | // Uncomment the code below if you caught |
| 132 | // exception because of k[1] is NULL. |
| 133 | // Nullifies the whole array of "k" |
| 134 | //int i = TMaxArgs; |
| 135 | //while (--i) |
| 136 | // k[i] = NULL; |
| 137 | |
| 138 | #endif |
| 139 | TStatus TheStatus = TSuccess; |
| 140 | |
| 141 | CMN_GET_STACK( n, k ); |
| 142 | |
| 143 | if( TsmMtblArray[el] && TsmMtblArray[el][msg] ) |
| 144 | TheStatus = TsmMtblArray[el][msg]( data, n, k ); |
| 145 | return TheStatus; |
| 146 | } |
| 147 | |
| 148 | static void |
| 149 | TsmFreeList( tsm_struct s ) |
| 150 | { |
| 151 | if ( !s ) |
| 152 | return; |
| 153 | |
| 154 | if( _Allocator.IsNull() ) |
| 155 | return ; |
| 156 | |
| 157 | tsm_node node, prev; |
| 158 | Tint num, i; |
| 159 | |
| 160 | num = s->elemListHead.header.num; |
| 161 | node = s->elemListHead.next; |
| 162 | |
| 163 | for( i=0; i<num; i++ ) |
| 164 | { |
| 165 | TsmSendMessage( node->elem.el, Delete, node->elem.data, 0 ); |
| 166 | prev = node; |
| 167 | node = node->next; |
| 168 | delete prev; |
| 169 | } |
| 170 | |
| 171 | s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead); |
| 172 | s->elemListHead.header.num = 0; |
| 173 | return; |
| 174 | } |
| 175 | |
| 176 | TStatus |
| 177 | TsmOpenStructure( Tint stid ) |
| 178 | { |
| 179 | tsm_struct s = 0; |
| 180 | |
| 181 | if( _Allocator.IsNull() ) |
| 182 | return TFailure; |
| 183 | |
| 184 | if( context.ind != TsmStructureNotOpen ) |
| 185 | return TFailure; /* Some structure already open */ |
| 186 | |
| 187 | if ( !_StructMap.IsBound(stid) ){ |
| 188 | s = new TSM_STRUCT(); |
| 189 | if ( !s ) |
| 190 | return TFailure; // Memory allocation failed |
| 191 | |
| 192 | _StructMap.Bind( stid, s ); |
| 193 | s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead); |
| 194 | s->elemListHead.header.num = 0; |
| 195 | } |
| 196 | |
| 197 | s = _StructMap.Find(stid); |
| 198 | |
| 199 | context.s = s; |
| 200 | context.stid = stid; |
| 201 | // Make the context point at the last node of the structure, |
| 202 | // this is the list head in case of an empty structure |
| 203 | context.ind = s->elemListHead.header.num; |
| 204 | context.n = s->elemListHead.prev; |
| 205 | |
| 206 | /* Ajout CAL, 14/09/95 */ |
| 207 | /* on force l'update_state de toutes les wks a TNotDone */ |
| 208 | TsmInitUpdateState (); |
| 209 | |
| 210 | return TSuccess; |
| 211 | } |
| 212 | |
| 213 | TStatus |
| 214 | TsmCloseStructure() |
| 215 | { |
| 216 | if( context.ind == TsmStructureNotOpen ) |
| 217 | return TFailure; /* No structure currently open */ |
| 218 | |
| 219 | context.ind = TsmStructureNotOpen; |
| 220 | |
| 221 | return TSuccess; |
| 222 | } |
| 223 | |
| 224 | |
| 225 | TStatus |
| 226 | TsmDisplayStructure( Tint stid, Tint wsid ) |
| 227 | { |
| 228 | TSM_ELEM_DATA data; |
| 229 | CMN_KEY key; |
| 230 | |
| 231 | TglActiveWs = wsid; |
| 232 | |
| 233 | if( context.ind != TsmStructureNotOpen ) |
| 234 | return TFailure; /* Some structure currently open */ |
| 235 | |
| 236 | key.id = wsid; |
| 237 | data.ldata = stid; |
| 238 | TsmSendMessage( TelExecuteStructure, DisplayTraverse, data, 1, &key ); |
| 239 | |
| 240 | return TSuccess; |
| 241 | } |
| 242 | |
| 243 | TStatus |
| 244 | TsmPrintStructure( Tint stid ) |
| 245 | { |
| 246 | tsm_node node; |
| 247 | Tint i, num; |
| 248 | tsm_struct s; |
| 249 | |
| 250 | if( context.ind != TsmStructureNotOpen ) |
| 251 | return TFailure; /* Some structure currently open */ |
| 252 | |
| 253 | if ( _StructMap.IsEmpty() ) |
| 254 | return TFailure; /* No structure created yet */ |
| 255 | |
| 256 | /* Obtain structure pointer from hash table */ |
| 257 | if ( !_StructMap.IsBound(stid) ) |
| 258 | return TFailure; /* Non-existent structure */ |
| 259 | |
| 260 | s = _StructMap.Find(stid); |
| 261 | |
| 262 | printf( "\nPRINT:" ); |
| 263 | printf( "\n\tSTRUCTURE ID = %d", stid ); |
| 264 | if( !s ){ |
| 265 | num = 0; |
| 266 | node = 0; |
| 267 | } |
| 268 | else{ |
| 269 | num = s->elemListHead.header.num; |
| 270 | node = s->elemListHead.next; |
| 271 | } |
| 272 | |
| 273 | printf( "\n\tNUMBER OF ELEMENTS = %d", num); |
| 274 | printf( "\n" ); |
| 275 | |
| 276 | /* For each element Send Message Print */ |
| 277 | for( i = 0; i < num; i++ ){ |
| 278 | printf("\n\tElement[%d] : ", i+1); |
| 279 | TsmSendMessage( node->elem.el, Print, node->elem.data, 0 ); |
| 280 | node = node->next; |
| 281 | } |
| 282 | |
| 283 | return TSuccess; |
| 284 | } |
| 285 | |
| 286 | TStatus |
| 287 | TsmAddToStructure( TelType el, Tint n, ... ) |
| 288 | { |
| 289 | TSM_ELEM_DATA data; |
| 290 | #if defined (SOLARIS) || defined (IRIXO32) |
| 291 | cmn_key *k; |
| 292 | #else |
| 293 | cmn_key k[TMaxArgs]; |
| 294 | #endif |
| 295 | |
| 296 | if( context.ind == TsmStructureNotOpen ) |
| 297 | return TFailure; /* No structure currently open */ |
| 298 | |
| 299 | CMN_GET_STACK( n, k ); |
| 300 | data.pdata = &data; |
| 301 | if( TsmSendMessage( el, Add, data, -n, k ) == TFailure ) |
| 302 | return TFailure; |
| 303 | |
| 304 | if( edit_mode == TEditReplace ){ |
| 305 | TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 ); |
| 306 | } |
| 307 | else{ |
| 308 | tsm_node node = new TSM_NODE(); |
| 309 | |
| 310 | if( !node ) |
| 311 | return TFailure; |
| 312 | |
| 313 | /* insert the node in the linked list after the current node */ |
| 314 | node->prev = context.n; |
| 315 | node->next = context.n->next; |
| 316 | context.n->next = node; |
| 317 | node->next->prev = node; |
| 318 | |
| 319 | /* Make this node as current node */ |
| 320 | context.n = node; |
| 321 | context.ind++; |
| 322 | |
| 323 | /* Increment the no of elements */ |
| 324 | context.s->elemListHead.header.num++; |
| 325 | } |
| 326 | |
| 327 | context.n->elem.el = el; |
| 328 | context.n->elem.data = data; |
| 329 | |
| 330 | return TSuccess; |
| 331 | } |
| 332 | |
| 333 | TStatus |
| 334 | TsmDeleteStructure( Tint stid ) |
| 335 | { |
| 336 | if( context.ind != TsmStructureNotOpen && context.stid == stid ) |
| 337 | return TFailure; /* Same structure currently open */ |
| 338 | |
| 339 | if ( _StructMap.IsEmpty() ) |
| 340 | return TFailure; /* No structure created yet */ |
| 341 | |
| 342 | if ( !_StructMap.IsBound(stid) ) |
| 343 | return TFailure; /* Non-existent structure */ |
| 344 | |
| 345 | tsm_struct s = _StructMap.ChangeFind(stid); |
| 346 | |
| 347 | if( stid == context.stid ){ |
| 348 | context.stid = TsmInvalidStructure; |
| 349 | // Ensure the context doesn't point to freed memory |
| 350 | context.s = 0; |
| 351 | context.n = 0; |
| 352 | } |
| 353 | |
| 354 | if( s ){ |
| 355 | TsmFreeList( s ); |
| 356 | |
| 357 | /* Free structure memory */ |
| 358 | delete s; |
| 359 | } |
| 360 | |
| 361 | /* Remove hash table entry */ |
| 362 | _StructMap.UnBind( stid ); |
| 363 | |
| 364 | /* Ajout BGN, 27/05/97 */ |
| 365 | /* on force l'update_state de toutes les wks a TNotDone */ |
| 366 | TsmInitUpdateState (); |
| 367 | |
| 368 | return TSuccess; |
| 369 | } |
| 370 | |
| 371 | TEditMode |
| 372 | TsmSetEditMode( TEditMode mode ) |
| 373 | { |
| 374 | TEditMode m; |
| 375 | |
| 376 | m = edit_mode; |
| 377 | |
| 378 | /* Set static variable for mode */ |
| 379 | edit_mode = mode; |
| 380 | |
| 381 | /* return previous mode */ |
| 382 | return m; |
| 383 | } |
| 384 | |
| 385 | TStatus |
| 386 | TsmDeleteElement() |
| 387 | { |
| 388 | tsm_node node; |
| 389 | |
| 390 | if( context.ind == TsmStructureNotOpen ) |
| 391 | return TFailure; /* No structure currently open */ |
| 392 | |
| 393 | // Zero ind means the currently open structure is empty |
| 394 | // or the current node is the list head -> nothing to delete |
| 395 | // See also TsmSetElementPointer() |
| 396 | if( !context.ind ) |
| 397 | return TFailure; |
| 398 | |
| 399 | /* Send message DELETE element */ |
| 400 | TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 ); |
| 401 | |
| 402 | node = context.n; |
| 403 | node->prev->next = node->next; |
| 404 | node->next->prev = node->prev; |
| 405 | |
| 406 | /* make previous node as current node */ |
| 407 | context.n = node->prev; |
| 408 | context.ind--; |
| 409 | |
| 410 | /* Decrement the no of elements */ |
| 411 | context.s->elemListHead.header.num--; |
| 412 | |
| 413 | /* free the linked list node */ |
| 414 | delete node; |
| 415 | |
| 416 | return TSuccess; |
| 417 | } |
| 418 | |
| 419 | TStatus |
| 420 | TsmDeleteElementsBetweenLabels( Tint label_id1, Tint label_id2 ) |
| 421 | /* label_id1 & label_id2 exclusive */ |
| 422 | { |
| 423 | Tint elem1, elem2; |
| 424 | |
| 425 | if( context.ind == TsmStructureNotOpen ) |
| 426 | return TFailure; /* No structure currently open */ |
| 427 | |
| 428 | TsmSetElementPointer( 0 ); |
| 429 | |
| 430 | if( TsmSetElementPointerAtLabel( label_id1 ) == TFailure) |
| 431 | return TFailure; |
| 432 | elem1 = context.ind; |
| 433 | |
| 434 | if( TsmSetElementPointerAtLabel( label_id2 ) == TFailure) |
| 435 | return TFailure; |
| 436 | elem2 = context.ind; |
| 437 | |
| 438 | TsmDeleteElementRange( elem1, elem2 ); |
| 439 | |
| 440 | return TSuccess; |
| 441 | } |
| 442 | |
| 443 | TStatus |
| 444 | TsmDeleteElementRange( Tint elem1, Tint elem2 ) /* elem1 & elem2 exclusive */ |
| 445 | { |
| 446 | if( context.ind == TsmStructureNotOpen ) |
| 447 | return TFailure; /* No structure currently open */ |
| 448 | |
| 449 | TsmSetElementPointer( elem2 - 1 ); |
| 450 | while( context.ind != elem1 && context.ind ) |
| 451 | TsmDeleteElement(); |
| 452 | |
| 453 | return TSuccess; |
| 454 | } |
| 455 | |
| 456 | TStatus |
| 457 | TsmSetElementPointer( Tint index ) |
| 458 | { |
| 459 | if( context.ind == TsmStructureNotOpen ) |
| 460 | return TFailure; /* No structure currently open */ |
| 461 | |
| 462 | /* Set static variable accordingly */ |
| 463 | if( context.ind == index ){ |
| 464 | return TSuccess; |
| 465 | } |
| 466 | if( index >= context.s->elemListHead.header.num ){ |
| 467 | index = context.s->elemListHead.header.num; |
| 468 | context.n = context.s->elemListHead.prev; |
| 469 | } |
| 470 | else if( index <= 0 ){ |
| 471 | index = 0; |
| 472 | context.n = (tsm_node)&(context.s->elemListHead); |
| 473 | } |
| 474 | else{ |
| 475 | Tint a, b, c, d; |
| 476 | tsm_node node; |
| 477 | |
| 478 | a = index - 0; |
| 479 | b = context.ind - index; if( b < 0 ) b = -b; /* b = labs(b) */ |
| 480 | c = context.s->elemListHead.header.num - index; |
| 481 | d = ( a < b ) ? ( a < c ? a : c ) : ( b < c ? b : c ) ; |
| 482 | |
| 483 | if( a == d ){ |
| 484 | /* Traverse from head in forward direction */ |
| 485 | d = index-1; |
| 486 | node = context.s->elemListHead.next; |
| 487 | while( d-- ){ |
| 488 | node = node->next; |
| 489 | } |
| 490 | } |
| 491 | else if( b == d ){ |
| 492 | /* Traverse from current node in appropriate direction */ |
| 493 | node = context.n; |
| 494 | d = context.ind; |
| 495 | if( context.ind < index ){ |
| 496 | while( d != index ){ |
| 497 | node = node->next; |
| 498 | d++; |
| 499 | } |
| 500 | } |
| 501 | else{ |
| 502 | while( d != index ){ |
| 503 | node = node->prev; |
| 504 | d--; |
| 505 | } |
| 506 | } |
| 507 | } |
| 508 | else{ /* ( c == d ) */ |
| 509 | /* Traverse from head in backward direction */ |
| 510 | d = context.s->elemListHead.header.num; |
| 511 | node = context.s->elemListHead.prev; |
| 512 | while( d != index ){ |
| 513 | node = node->prev; |
| 514 | d--; |
| 515 | } |
| 516 | } |
| 517 | |
| 518 | context.n = node; |
| 519 | } |
| 520 | |
| 521 | context.ind = index; |
| 522 | |
| 523 | return TSuccess; |
| 524 | } |
| 525 | |
| 526 | |
| 527 | TStatus |
| 528 | TsmSetElementPointerAtLabel( Tint label_id ) |
| 529 | { |
| 530 | Tint i, num; |
| 531 | tsm_node node; |
| 532 | |
| 533 | if( context.ind == TsmStructureNotOpen ) |
| 534 | return TFailure; /* No structure currently open */ |
| 535 | |
| 536 | num = context.s->elemListHead.header.num; |
| 537 | for( i=context.ind+1, node=context.n->next; i<=num; i++, node=node->next ){ |
| 538 | if( node->elem.el == TelLabel && node->elem.data.ldata == label_id ){ |
| 539 | context.ind = i; |
| 540 | context.n = node; |
| 541 | return TSuccess; |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | return TFailure; |
| 546 | } |
| 547 | |
| 548 | TStatus |
| 549 | TsmOffsetElementPointer( Tint offset ) |
| 550 | { |
| 551 | return TsmSetElementPointer( context.ind + offset ); |
| 552 | } |
| 553 | |
| 554 | TStatus |
| 555 | TsmGetStructure( Tint stid, Tint *num, tsm_node *n ) |
| 556 | { |
| 557 | if ( _StructMap.IsEmpty() ) |
| 558 | return TFailure; /* No structure created yet */ |
| 559 | |
| 560 | if ( !_StructMap.IsBound(stid) ) |
| 561 | return TFailure; /* Non-existent structure */ |
| 562 | |
| 563 | tsm_struct s = _StructMap.Find(stid); |
| 564 | |
| 565 | *num = s ? s->elemListHead.header.num : 0; |
| 566 | // Here we cannot return a pointer to the structure's list head, |
| 567 | // as it will wrongly interpreted as a regular pointer to TSM_NODE, |
| 568 | // thus returning null pointer - this should be checked by callers! |
| 569 | *n = s ? s->elemListHead.next : 0; |
| 570 | |
| 571 | return TSuccess; |
| 572 | } |
| 573 | |
| 574 | static TStatus |
| 575 | GetDepth( Tint stid, Tint *depth ) |
| 576 | { |
| 577 | tsm_struct s; |
| 578 | Tint i, d, b, num; |
| 579 | |
| 580 | if ( _StructMap.IsEmpty() ) |
| 581 | return TFailure; /* No structure created yet */ |
| 582 | |
| 583 | if ( !_StructMap.IsBound(stid) ) |
| 584 | return TFailure; /* Non-existent structure */ |
| 585 | |
| 586 | s = _StructMap.Find(stid); |
| 587 | |
| 588 | (*depth)++; |
| 589 | d = b = *depth; |
| 590 | |
| 591 | if( s ){ |
| 592 | num = s->elemListHead.header.num; |
| 593 | tsm_node node = s->elemListHead.next; |
| 594 | for( i = 0; i < num; i++ ){ |
| 595 | if( node->elem.el == TelExecuteStructure ){ |
| 596 | GetDepth( node->elem.data.ldata, &d ); |
| 597 | if( *depth < d ) |
| 598 | *depth = d; |
| 599 | } |
| 600 | d = b; |
| 601 | node = node->next; |
| 602 | } |
| 603 | } |
| 604 | |
| 605 | return TSuccess; |
| 606 | } |
| 607 | |
| 608 | |
| 609 | TStatus |
| 610 | TsmGetStructureDepth( Tint stid, Tint *depth ) |
| 611 | { |
| 612 | *depth = 0; |
| 613 | |
| 614 | GetDepth( stid, depth ); |
| 615 | return TSuccess; |
| 616 | } |
| 617 | |
| 618 | TStatus |
| 619 | TsmGetCurElem( TSM_ELEM *elem ) |
| 620 | { |
| 621 | // Zero ind means no current element |
| 622 | if( context.ind == TsmStructureNotOpen || |
| 623 | !context.ind ) |
| 624 | return TFailure; |
| 625 | |
| 626 | *elem = context.n->elem; |
| 627 | return TSuccess; |
| 628 | } |
| 629 | |
| 630 | TStatus |
| 631 | TsmGetCurElemPtr( Tint *ptr ) |
| 632 | { |
| 633 | // Zero ind means no current element |
| 634 | if( context.ind == TsmStructureNotOpen || |
| 635 | !context.ind ) |
| 636 | return TFailure; |
| 637 | |
| 638 | *ptr = context.ind; |
| 639 | return TSuccess; |
| 640 | } |