os/graphics/graphicscomposition/openwfcompositionengine/common/src/owfattributes.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* Copyright (c) 2009-2010 The Khronos Group Inc.
sl@0
     2
 * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
sl@0
     3
 *
sl@0
     4
 * Permission is hereby granted, free of charge, to any person obtaining a
sl@0
     5
 * copy of this software and/or associated documentation files (the
sl@0
     6
 * "Materials"), to deal in the Materials without restriction, including
sl@0
     7
 * without limitation the rights to use, copy, modify, merge, publish,
sl@0
     8
 * distribute, sublicense, and/or sell copies of the Materials, and to
sl@0
     9
 * permit persons to whom the Materials are furnished to do so, subject to
sl@0
    10
 * the following conditions:
sl@0
    11
 *
sl@0
    12
 * The above copyright notice and this permission notice shall be included
sl@0
    13
 * in all copies or substantial portions of the Materials.
sl@0
    14
 *
sl@0
    15
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
sl@0
    16
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
sl@0
    17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
sl@0
    18
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
sl@0
    19
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
sl@0
    20
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
sl@0
    21
 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
sl@0
    22
 */
sl@0
    23
sl@0
    24
sl@0
    25
sl@0
    26
#ifdef __cplusplus
sl@0
    27
extern "C" {
sl@0
    28
#endif
sl@0
    29
sl@0
    30
sl@0
    31
#include <stdio.h>
sl@0
    32
#include <stdlib.h>
sl@0
    33
#include <string.h>
sl@0
    34
#include <math.h>
sl@0
    35
sl@0
    36
#include "owfattributes.h"
sl@0
    37
#include "owfmemory.h"
sl@0
    38
#include "owfdebug.h"
sl@0
    39
sl@0
    40
#define OWF_ATTRIB_RANGE_START            (0)
sl@0
    41
#define OWF_ATTRIB_RANGE_UNINITIALIZED    (-1)
sl@0
    42
sl@0
    43
static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, OWFint aDirtyFlag, OWFint aCopyTo,OWFint aCopyFrom);
sl@0
    44
 
sl@0
    45
  /*
sl@0
    46
  This attribute class is not used for WFC element attributes because elements are 
sl@0
    47
  completely cloned in the committed scene.
sl@0
    48
  [This class could be replaced with 3 copies of a much simpler writable attributes raw 
sl@0
    49
  structure with simple data members, and the whole structure copied each commit.] 
sl@0
    50
  Normal attribute values have three pointers indexed via an array:
sl@0
    51
     COMMITTED_ATTR_VALUE_INDEX:
sl@0
    52
         Attribute values used by the scene 
sl@0
    53
             - points to named variables directly used by the compositor
sl@0
    54
     WORKING_ATTR_VALUE_INDEX:
sl@0
    55
         Attribute values that may be set by the client, if they are not read-only.
sl@0
    56
     SNAPSHOT_ATTR_VALUE_INDEX
sl@0
    57
         A copy of the client-set attribute values following a client call to wfcCommit
sl@0
    58
         The copy is then protected against further modification by the client until 
sl@0
    59
         the committed scene is updated and displayed.
sl@0
    60
  The Working and Snapshot writable attributes require additional cache storage, 
sl@0
    61
  which is managed by the lifetime of the attribute list.
sl@0
    62
  Read-only attributes point all three pointers at the named compositor variables.
sl@0
    63
  Currently, there are relatively few writable attributes so it is reasonable 
sl@0
    64
  to individually dynamically allocate each cache. It would be better to allocate 
sl@0
    65
  a single block sized after the attributes have been registered.  
sl@0
    66
  
sl@0
    67
  Internal code is expected to read or write to member variables that are abstracted 
sl@0
    68
  by read-only attributes. However they must not write directly to member variables 
sl@0
    69
  masked by writable attributes after the initial "commit" to working. The code does 
sl@0
    70
  not currently use const instances to enforce this behavior.
sl@0
    71
 */
sl@0
    72
#define COND_FAIL_NR(ctx, condition, error) \
sl@0
    73
    if (!(condition)) { \
sl@0
    74
        if (ctx) { \
sl@0
    75
            (ctx)->last_error = error; \
sl@0
    76
        } \
sl@0
    77
        return; \
sl@0
    78
    }
sl@0
    79
sl@0
    80
#define COND_FAIL(ctx, condition, error, r) \
sl@0
    81
    if (!(condition)) { \
sl@0
    82
        if (ctx) { \
sl@0
    83
            (ctx)->last_error = error; \
sl@0
    84
        } \
sl@0
    85
        return r; \
sl@0
    86
    }
sl@0
    87
	
sl@0
    88
// NS here means No Set as we are not setting the last_error member of the context.
sl@0
    89
// These are used when we are testing the context itself so setting the last_error
sl@0
    90
// member is itself is an error
sl@0
    91
#define COND_FAIL_NR_NS(condition) \
sl@0
    92
    if (!(condition)) { \
sl@0
    93
        return; \
sl@0
    94
    }
sl@0
    95
sl@0
    96
#define COND_FAIL_NS(condition, r) \
sl@0
    97
    if (!(condition)) { \
sl@0
    98
        return r; \
sl@0
    99
    }
sl@0
   100
sl@0
   101
#define CHECK_INDEX_NR(ctx, index, error) \
sl@0
   102
    if (index < (ctx)->range_start || index > (ctx)->range_end) { \
sl@0
   103
        (ctx)->last_error = error; \
sl@0
   104
        return; \
sl@0
   105
    }
sl@0
   106
sl@0
   107
#define CHECK_INDEX(ctx, index, error, r) \
sl@0
   108
    if (index < (ctx)->range_start || index > (ctx)->range_end) { \
sl@0
   109
        (ctx)->last_error = error; \
sl@0
   110
        return r; \
sl@0
   111
    }
sl@0
   112
sl@0
   113
#define CHECK_BAD_NR(ctx, index) \
sl@0
   114
    CHECK_INDEX_NR(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE); \
sl@0
   115
    if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
sl@0
   116
        (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
sl@0
   117
        return; \
sl@0
   118
    }
sl@0
   119
sl@0
   120
#define CHECK_BAD(ctx, index, r) \
sl@0
   121
    CHECK_INDEX(ctx, index, ATTR_ERROR_INVALID_ATTRIBUTE, r); \
sl@0
   122
    if ((ctx)->attributes[index-(ctx)->range_start].attr_info.type == AT_UNDEFINED) { \
sl@0
   123
        (ctx)->last_error = ATTR_ERROR_INVALID_ATTRIBUTE; \
sl@0
   124
        return r; \
sl@0
   125
    }
sl@0
   126
sl@0
   127
#define SET_ERROR(ctx, err) \
sl@0
   128
    if ((ctx)->last_error == ATTR_ERROR_NONE) { \
sl@0
   129
        (ctx)->last_error = err; \
sl@0
   130
    }
sl@0
   131
sl@0
   132
sl@0
   133
/*
sl@0
   134
=============================================================================
sl@0
   135
ATTRIBUTE CONTEXT MANAGEMENT FUNCTIONS
sl@0
   136
=============================================================================
sl@0
   137
*/
sl@0
   138
sl@0
   139
/*!
sl@0
   140
 * \brief Initializes attribute context
sl@0
   141
 *
sl@0
   142
 * \param aContext Attribute context to initialize
sl@0
   143
 * \param aStart Attribute range start
sl@0
   144
 * \param aEnd Attribute range end. Must be greater than range start.
sl@0
   145
 *
sl@0
   146
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   147
 * ATTR_ERROR_NO_MEMORY
sl@0
   148
 */
sl@0
   149
OWF_API_CALL void
sl@0
   150
OWF_AttributeList_Create(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   151
                         OWFint aStart,
sl@0
   152
                         OWFint aEnd)
sl@0
   153
{
sl@0
   154
    OWF_ATTRIBUTE*          temp = NULL;
sl@0
   155
sl@0
   156
    COND_FAIL_NR_NS(aContext);
sl@0
   157
    COND_FAIL_NR(aContext, aEnd >= 0, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   158
    COND_FAIL_NR(aContext, aEnd >= aStart, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   159
sl@0
   160
    aContext->range_start = OWF_ATTRIB_RANGE_START;
sl@0
   161
    aContext->range_end = OWF_ATTRIB_RANGE_UNINITIALIZED;
sl@0
   162
sl@0
   163
    temp = (OWF_ATTRIBUTE*) xalloc(aEnd - aStart + 1, sizeof(OWF_ATTRIBUTE));
sl@0
   164
    COND_FAIL_NR(aContext, temp, ATTR_ERROR_NO_MEMORY);
sl@0
   165
sl@0
   166
    memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
sl@0
   167
sl@0
   168
    aContext->range_start = aStart;
sl@0
   169
    aContext->range_end = aEnd;
sl@0
   170
    aContext->attributes = temp;
sl@0
   171
sl@0
   172
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   173
    return;
sl@0
   174
}
sl@0
   175
sl@0
   176
/*!
sl@0
   177
 * \brief Destroy attribute context and free any resources (memory
sl@0
   178
 * blocks) allocated to it. All attributes are destroyed.
sl@0
   179
 *
sl@0
   180
 * \param aContext Attribute context to destroy
sl@0
   181
 *
sl@0
   182
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   183
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   184
 */
sl@0
   185
OWF_API_CALL void
sl@0
   186
OWF_AttributeList_Destroy(OWF_ATTRIBUTE_LIST* aContext)
sl@0
   187
{
sl@0
   188
    OWFint                 count = 0;
sl@0
   189
    OWFint                 at = 0;
sl@0
   190
    OWFint                 cache = 0;
sl@0
   191
sl@0
   192
    COND_FAIL_NR_NS(aContext);
sl@0
   193
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   194
sl@0
   195
    count = aContext->range_end - aContext->range_start;
sl@0
   196
    for (at = 0; at <= count; at++) {
sl@0
   197
sl@0
   198
        OWF_ATTRIBUTE* attr = &aContext->attributes[at];
sl@0
   199
        if (!attr->attr_info.readonly)
sl@0
   200
            {
sl@0
   201
            for (cache=0;cache<NUM_ATTR_VALUE_COPIES;cache++)
sl@0
   202
                {
sl@0
   203
                if (cache!=COMMITTED_ATTR_VALUE_INDEX)
sl@0
   204
                    {
sl@0
   205
                    xfree(attr->attr_value[cache].gen_ptr);
sl@0
   206
                    }
sl@0
   207
                }
sl@0
   208
            }
sl@0
   209
    }
sl@0
   210
sl@0
   211
    xfree(aContext->attributes);
sl@0
   212
    memset(aContext, 0, sizeof(OWF_ATTRIBUTE_LIST));
sl@0
   213
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   214
    return;
sl@0
   215
}
sl@0
   216
sl@0
   217
/*
sl@0
   218
sl@0
   219
sl@0
   220
 */
sl@0
   221
OWF_API_CALL OWF_ATTRIBUTE_LIST_STATUS
sl@0
   222
OWF_AttributeList_GetError(OWF_ATTRIBUTE_LIST* aContext)
sl@0
   223
{
sl@0
   224
    OWF_ATTRIBUTE_LIST_STATUS   error;
sl@0
   225
sl@0
   226
    if (!aContext) {
sl@0
   227
        return ATTR_ERROR_INVALID_ARGUMENT;
sl@0
   228
    }
sl@0
   229
    error = aContext->last_error;
sl@0
   230
    aContext->last_error = ATTR_ERROR_NONE;
sl@0
   231
    return error;
sl@0
   232
}
sl@0
   233
sl@0
   234
/*
sl@0
   235
=============================================================================
sl@0
   236
INITIALIZATION FUNCTIONS
sl@0
   237
=============================================================================
sl@0
   238
*/
sl@0
   239
sl@0
   240
static void OWF_Attribute_Init(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   241
                               OWFint aName,
sl@0
   242
                               OWF_ATTRIBUTE_TYPE aType,
sl@0
   243
                               OWFint aLength,
sl@0
   244
                               void* aValue,
sl@0
   245
                               OWFboolean aRdOnly)
sl@0
   246
{
sl@0
   247
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   248
    void*                   cache = NULL;
sl@0
   249
    OWFint                  itemSize;
sl@0
   250
    OWFint                  arraySize;
sl@0
   251
    OWFint                  copy;
sl@0
   252
    OWFint                  index;
sl@0
   253
	
sl@0
   254
	COND_FAIL_NR_NS(aContext);
sl@0
   255
	CHECK_INDEX_NR(aContext, aName, ATTR_ERROR_INVALID_ATTRIBUTE);
sl@0
   256
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   257
    COND_FAIL_NR(aContext, aLength < MAX_ATTR_LENGTH, ATTR_ERROR_CANT_HANDLE);
sl@0
   258
    COND_FAIL_NR(aContext, aType != AT_UNDEFINED, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   259
	
sl@0
   260
	index = aName - aContext->range_start;
sl@0
   261
sl@0
   262
    attr = &aContext->attributes[index];
sl@0
   263
    
sl@0
   264
    memset(attr, 0, sizeof(OWF_ATTRIBUTE));
sl@0
   265
sl@0
   266
    /* when allocin', size DOES matter */
sl@0
   267
    if (aType == AT_INTEGER || aType == AT_BOOLEAN) {
sl@0
   268
        itemSize = sizeof(OWFint);
sl@0
   269
    } else {
sl@0
   270
        itemSize = sizeof(OWFfloat);
sl@0
   271
    }
sl@0
   272
    arraySize=itemSize*aLength;
sl@0
   273
sl@0
   274
    /* don't allocate cache for read-only 'butes */
sl@0
   275
    attr->attr_info.type        = aType;
sl@0
   276
    attr->attr_info.length      = aLength;
sl@0
   277
    attr->attr_info.readonly    = aRdOnly;
sl@0
   278
    attr->attr_info.size        = itemSize;
sl@0
   279
    if (aRdOnly)
sl@0
   280
        {
sl@0
   281
        for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
sl@0
   282
            {
sl@0
   283
            attr->attr_value[copy].gen_ptr = aValue;
sl@0
   284
            }
sl@0
   285
        }
sl@0
   286
    else
sl@0
   287
        {
sl@0
   288
        for (copy=0;copy<NUM_ATTR_VALUE_COPIES;copy++)
sl@0
   289
            {
sl@0
   290
            if (copy==COMMITTED_ATTR_VALUE_INDEX)
sl@0
   291
                {
sl@0
   292
                 attr->attr_value[COMMITTED_ATTR_VALUE_INDEX].gen_ptr = aValue;
sl@0
   293
                }
sl@0
   294
            else
sl@0
   295
                {
sl@0
   296
                cache = xalloc(arraySize,1);
sl@0
   297
                COND_FAIL_NR(aContext, NULL != cache, ATTR_ERROR_NO_MEMORY);
sl@0
   298
                attr->attr_value[copy].gen_ptr = cache;
sl@0
   299
                }
sl@0
   300
             }
sl@0
   301
       }
sl@0
   302
sl@0
   303
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   304
sl@0
   305
}
sl@0
   306
sl@0
   307
/*
sl@0
   308
 * \brief Intialize integer attribute
sl@0
   309
 *
sl@0
   310
 * \param aContext Attibute context
sl@0
   311
 * \param aName Attribute name
sl@0
   312
 * \param aValue Attribute initial value
sl@0
   313
 * \param aRdOnly Read-only flag
sl@0
   314
 *
sl@0
   315
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   316
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   317
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   318
 */
sl@0
   319
OWF_API_CALL void
sl@0
   320
OWF_Attribute_Initi(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   321
                    OWFint aName,
sl@0
   322
                    OWF_INT_REF aValue,
sl@0
   323
                    OWFboolean aRdOnly)
sl@0
   324
{
sl@0
   325
    OWF_Attribute_Init(aContext, aName, AT_INTEGER, 1, aValue, aRdOnly);
sl@0
   326
}
sl@0
   327
sl@0
   328
/*
sl@0
   329
 * \brief Initialize float attribute
sl@0
   330
 *
sl@0
   331
 * \param aContext Attribute context
sl@0
   332
 * \param aName Attribute name
sl@0
   333
 * \param aValue Initial value for attribute
sl@0
   334
 * \param aRdOnly Read-only flag
sl@0
   335
 *
sl@0
   336
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   337
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   338
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   339
 */
sl@0
   340
OWF_API_CALL void
sl@0
   341
OWF_Attribute_Initf(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   342
                    OWFint aName,
sl@0
   343
                    OWF_FLOAT_REF aValue,
sl@0
   344
                    OWFboolean aRdOnly)
sl@0
   345
{
sl@0
   346
    OWF_Attribute_Init(aContext, aName, AT_FLOAT, 1, aValue, aRdOnly);
sl@0
   347
}
sl@0
   348
sl@0
   349
/*
sl@0
   350
 * \brief Initialize boolean attribute
sl@0
   351
 *
sl@0
   352
 * \param aContext Attribute context
sl@0
   353
 * \param aName Attribute name
sl@0
   354
 * \param aValue Initial value for attribute
sl@0
   355
 * \param aRdOnly Read-only flag
sl@0
   356
 *
sl@0
   357
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   358
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   359
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   360
 */
sl@0
   361
OWF_API_CALL void
sl@0
   362
OWF_Attribute_Initb(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   363
                    OWFint aName,
sl@0
   364
                    OWF_BOOL_REF aValue,
sl@0
   365
                    OWFboolean aRdOnly)
sl@0
   366
{
sl@0
   367
    OWF_Attribute_Init(aContext, aName, AT_BOOLEAN, 1, aValue, aRdOnly);
sl@0
   368
}
sl@0
   369
sl@0
   370
/*
sl@0
   371
 * \brief Initialize vector attribute
sl@0
   372
 *
sl@0
   373
 * \param aContext Attribute context
sl@0
   374
 * \param aName Attribute name
sl@0
   375
 * \param aLength Attribute (vector) length
sl@0
   376
 * \param aValues Initial value(s) for attribute
sl@0
   377
 * \param aRdOnly Read-only flag
sl@0
   378
 *
sl@0
   379
 * \return ATTR_ERROR_INVALID_ARGUMENT
sl@0
   380
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   381
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   382
 * ATTR_ERROR_CANT_HANDLE
sl@0
   383
 */
sl@0
   384
OWF_API_CALL void
sl@0
   385
OWF_Attribute_Initiv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   386
                     OWFint aName,
sl@0
   387
                     OWFint aLength,
sl@0
   388
                     OWF_INT_VECTOR_REF aValues,
sl@0
   389
                     OWFboolean aRdOnly)
sl@0
   390
{
sl@0
   391
    OWF_Attribute_Init(aContext, aName, AT_INTEGER, aLength, aValues, aRdOnly);
sl@0
   392
}
sl@0
   393
sl@0
   394
/*
sl@0
   395
 * \brief Initialize vector attribute
sl@0
   396
 *
sl@0
   397
 * \param aContext Attribute context
sl@0
   398
 * \param aName Attribute name
sl@0
   399
 * \param aLength Attribute (vector) length
sl@0
   400
 * \param aValues Initial value(s) for attributes
sl@0
   401
 * \param aRdOnly Read-only flag
sl@0
   402
 *
sl@0
   403
 * \return
sl@0
   404
 */
sl@0
   405
OWF_API_CALL void
sl@0
   406
OWF_Attribute_Initfv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   407
                     OWFint aName,
sl@0
   408
                     OWFint aLength,
sl@0
   409
                     OWF_FLOAT_VECTOR_REF aValues,
sl@0
   410
                     OWFboolean aRdOnly)
sl@0
   411
{
sl@0
   412
    OWF_Attribute_Init(aContext, aName, AT_FLOAT, aLength, aValues, aRdOnly);
sl@0
   413
}
sl@0
   414
sl@0
   415
/*
sl@0
   416
=============================================================================
sl@0
   417
GETTER FUNCTIONS
sl@0
   418
=============================================================================
sl@0
   419
*/
sl@0
   420
sl@0
   421
/*
sl@0
   422
 * \brief Get attribute integer value.
sl@0
   423
 *
sl@0
   424
 * \param aContext Attribute context
sl@0
   425
 * \param aName Attribute name
sl@0
   426
 *
sl@0
   427
 * \return Attribute integer value (floats are floor()ed). For vector
sl@0
   428
 * attributes the return value will be error ATTR_ERROR_INVALID_TYPE.
sl@0
   429
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   430
 * ATTR_ERROR_INVALID_CONTEXT
sl@0
   431
 */
sl@0
   432
OWF_API_CALL OWFint
sl@0
   433
OWF_Attribute_GetValuei(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   434
                        OWFint aName)
sl@0
   435
{
sl@0
   436
    OWFint                  index = 0;
sl@0
   437
    OWF_ATTRIBUTE*          attr = 0;
sl@0
   438
    OWFint                  result = 0;
sl@0
   439
sl@0
   440
    COND_FAIL_NS(aContext, 0); 
sl@0
   441
	COND_FAIL(aContext,
sl@0
   442
              aContext->attributes,
sl@0
   443
              ATTR_ERROR_INVALID_CONTEXT,
sl@0
   444
              0);
sl@0
   445
    CHECK_BAD(aContext, aName, 0);
sl@0
   446
sl@0
   447
sl@0
   448
    index = aName - aContext->range_start;
sl@0
   449
    attr = &aContext->attributes[index];
sl@0
   450
sl@0
   451
    COND_FAIL(aContext,
sl@0
   452
              1 == attr->attr_info.length,
sl@0
   453
              ATTR_ERROR_INVALID_TYPE,
sl@0
   454
              0);
sl@0
   455
sl@0
   456
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   457
sl@0
   458
    switch (attr->attr_info.type) {
sl@0
   459
        case AT_FLOAT: {
sl@0
   460
            result = floor(attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0]);
sl@0
   461
            break;
sl@0
   462
        }
sl@0
   463
sl@0
   464
        case AT_INTEGER:
sl@0
   465
        case AT_BOOLEAN: {
sl@0
   466
            result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
sl@0
   467
            break;
sl@0
   468
        }
sl@0
   469
sl@0
   470
        default: {
sl@0
   471
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   472
            break;
sl@0
   473
        }
sl@0
   474
    }
sl@0
   475
    return result;
sl@0
   476
}
sl@0
   477
sl@0
   478
/*
sl@0
   479
 * \brief Return boolean attribute value
sl@0
   480
 *
sl@0
   481
 * \param aContext Attribute context
sl@0
   482
 * \param aName Attribute name
sl@0
   483
 *
sl@0
   484
 * \return Attribute value
sl@0
   485
 * ATTR_ERROR_INVALID_ATTRIBUTE
sl@0
   486
 * ATTR_ERROR_INVALID_TYPE
sl@0
   487
 */
sl@0
   488
OWF_API_CALL OWFboolean
sl@0
   489
OWF_Attribute_GetValueb(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   490
                        OWFint aName)
sl@0
   491
{
sl@0
   492
    /* boolean is stored as int, must cast */
sl@0
   493
    return (OWFboolean) OWF_Attribute_GetValuei(aContext, aName);
sl@0
   494
}
sl@0
   495
sl@0
   496
/*
sl@0
   497
 * \brief Get attribute float value
sl@0
   498
 *
sl@0
   499
 * \param aContext
sl@0
   500
 * \param aName
sl@0
   501
 * \param aValue
sl@0
   502
 *
sl@0
   503
 * \return Attribute
sl@0
   504
 */
sl@0
   505
OWF_API_CALL OWFfloat
sl@0
   506
OWF_Attribute_GetValuef(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   507
                        OWFint aName)
sl@0
   508
{
sl@0
   509
    OWFint                 index = 0;
sl@0
   510
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   511
    OWFfloat                result = 0.f;
sl@0
   512
sl@0
   513
    COND_FAIL_NS(aContext, 0);
sl@0
   514
    COND_FAIL(aContext,
sl@0
   515
              aContext->attributes,
sl@0
   516
              ATTR_ERROR_INVALID_CONTEXT,
sl@0
   517
              0);
sl@0
   518
    CHECK_BAD(aContext, aName, 0);
sl@0
   519
sl@0
   520
sl@0
   521
    index = aName - aContext->range_start;
sl@0
   522
    attr = &aContext->attributes[index];
sl@0
   523
sl@0
   524
    COND_FAIL(aContext,
sl@0
   525
              1 == attr->attr_info.length,
sl@0
   526
              ATTR_ERROR_INVALID_TYPE,
sl@0
   527
              0);
sl@0
   528
sl@0
   529
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   530
    result = 0.f;
sl@0
   531
sl@0
   532
    switch (attr->attr_info.type) {
sl@0
   533
        case AT_FLOAT: {
sl@0
   534
            result = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0];
sl@0
   535
            break;
sl@0
   536
        }
sl@0
   537
sl@0
   538
        case AT_INTEGER:
sl@0
   539
        case AT_BOOLEAN: {
sl@0
   540
            result = (OWFfloat) attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0];
sl@0
   541
            break;
sl@0
   542
        }
sl@0
   543
sl@0
   544
        default: {
sl@0
   545
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   546
            break;
sl@0
   547
        }
sl@0
   548
    }
sl@0
   549
    return result;
sl@0
   550
}
sl@0
   551
sl@0
   552
/*
sl@0
   553
 * \brief
sl@0
   554
 *
sl@0
   555
 * \param aContext
sl@0
   556
 * \param aName
sl@0
   557
 * \param aSize
sl@0
   558
 * \param aValue
sl@0
   559
 *
sl@0
   560
 * \return
sl@0
   561
 */
sl@0
   562
OWF_API_CALL OWFint
sl@0
   563
OWF_Attribute_GetValueiv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   564
                         OWFint aName,
sl@0
   565
                         OWFint aLength,
sl@0
   566
                         OWFint* aValue)
sl@0
   567
{
sl@0
   568
    OWFint                 index = 0;
sl@0
   569
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   570
    OWFint                 count = 0;
sl@0
   571
sl@0
   572
    COND_FAIL_NS(aContext, 0);
sl@0
   573
    COND_FAIL(aContext,
sl@0
   574
              aContext->attributes,
sl@0
   575
              ATTR_ERROR_INVALID_CONTEXT,
sl@0
   576
              0);
sl@0
   577
    CHECK_BAD(aContext, aName, 0);
sl@0
   578
sl@0
   579
sl@0
   580
    index = aName - aContext->range_start;
sl@0
   581
    attr = &aContext->attributes[index];
sl@0
   582
sl@0
   583
    COND_FAIL(aContext,
sl@0
   584
              attr->attr_info.length >= 1,
sl@0
   585
              ATTR_ERROR_INVALID_TYPE,
sl@0
   586
              0);
sl@0
   587
sl@0
   588
    if (!aValue) {
sl@0
   589
        /* fetch size only */
sl@0
   590
        return attr->attr_info.length;
sl@0
   591
    }
sl@0
   592
sl@0
   593
    count = min(aLength, attr->attr_info.length);
sl@0
   594
sl@0
   595
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   596
sl@0
   597
    switch (attr->attr_info.type) {
sl@0
   598
        case AT_FLOAT: {
sl@0
   599
            OWFint i;
sl@0
   600
            OWFfloat* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value;
sl@0
   601
            for (i = 0; i < count; i++) {
sl@0
   602
                aValue[i] = floor(v[i]);
sl@0
   603
            }
sl@0
   604
            break;
sl@0
   605
        }
sl@0
   606
sl@0
   607
        case AT_BOOLEAN:
sl@0
   608
        case AT_INTEGER: {
sl@0
   609
            memcpy(aValue,
sl@0
   610
                   attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value,
sl@0
   611
                   count * attr->attr_info.size);
sl@0
   612
            break;
sl@0
   613
        }
sl@0
   614
sl@0
   615
        default: {
sl@0
   616
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   617
            break;
sl@0
   618
        }
sl@0
   619
    }
sl@0
   620
    return count;
sl@0
   621
}
sl@0
   622
sl@0
   623
/*
sl@0
   624
 * \brief
sl@0
   625
 *
sl@0
   626
 * \param aContext
sl@0
   627
 * \param aName
sl@0
   628
 * \param aSize
sl@0
   629
 * \param aValue
sl@0
   630
 *
sl@0
   631
 * \return
sl@0
   632
 */
sl@0
   633
OWF_API_CALL OWFint
sl@0
   634
OWF_Attribute_GetValuefv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   635
                         OWFint aName,
sl@0
   636
                         OWFint aLength,
sl@0
   637
                         OWFfloat* aValue)
sl@0
   638
{
sl@0
   639
    OWFint                 index = 0;
sl@0
   640
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   641
    OWFint                 count = 0;
sl@0
   642
sl@0
   643
    COND_FAIL_NS(aContext, 0);
sl@0
   644
    COND_FAIL(aContext,
sl@0
   645
              aContext->attributes,
sl@0
   646
              ATTR_ERROR_INVALID_CONTEXT,
sl@0
   647
              0);
sl@0
   648
    CHECK_BAD(aContext, aName, 0);
sl@0
   649
sl@0
   650
sl@0
   651
    index = aName - aContext->range_start;
sl@0
   652
    attr = &aContext->attributes[index];
sl@0
   653
sl@0
   654
    COND_FAIL(aContext,
sl@0
   655
              attr->attr_info.length >= 1,
sl@0
   656
              ATTR_ERROR_INVALID_TYPE, 0);
sl@0
   657
sl@0
   658
    if (!aValue) {
sl@0
   659
        /* fetch size only */
sl@0
   660
        return attr->attr_info.length;
sl@0
   661
    }
sl@0
   662
sl@0
   663
    count = min(aLength, attr->attr_info.length);
sl@0
   664
sl@0
   665
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   666
sl@0
   667
    switch (attr->attr_info.type) {
sl@0
   668
        case AT_FLOAT: {
sl@0
   669
            memcpy(aValue,
sl@0
   670
                   attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value,
sl@0
   671
                   count * attr->attr_info.size);
sl@0
   672
            break;
sl@0
   673
        }
sl@0
   674
sl@0
   675
        case AT_BOOLEAN:
sl@0
   676
        case AT_INTEGER: {
sl@0
   677
            OWFint i;
sl@0
   678
            OWFint* v = attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value;
sl@0
   679
            for (i = 0; i < count; i++) {
sl@0
   680
                aValue[i] = (OWFfloat) v[i];
sl@0
   681
            }
sl@0
   682
            break;
sl@0
   683
        }
sl@0
   684
sl@0
   685
        default: {
sl@0
   686
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   687
            break;
sl@0
   688
        }
sl@0
   689
    }
sl@0
   690
    return count;
sl@0
   691
}
sl@0
   692
sl@0
   693
/*
sl@0
   694
=============================================================================
sl@0
   695
SETTER FUNCTIONS
sl@0
   696
=============================================================================
sl@0
   697
*/
sl@0
   698
sl@0
   699
/*
sl@0
   700
 * \brief
sl@0
   701
 *
sl@0
   702
 * \param aContext
sl@0
   703
 * \param aName
sl@0
   704
 * \param aValue
sl@0
   705
 *
sl@0
   706
 * \return
sl@0
   707
 */
sl@0
   708
OWF_API_CALL void
sl@0
   709
OWF_Attribute_SetValuei(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   710
                        OWFint aName,
sl@0
   711
                        OWFint aValue)
sl@0
   712
{
sl@0
   713
    OWFint                 index = 0;
sl@0
   714
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   715
sl@0
   716
    COND_FAIL_NR_NS(aContext);
sl@0
   717
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   718
    CHECK_BAD_NR(aContext, aName);
sl@0
   719
sl@0
   720
sl@0
   721
    index = aName - aContext->range_start;
sl@0
   722
    attr = &aContext->attributes[index];
sl@0
   723
sl@0
   724
    COND_FAIL_NR(aContext,
sl@0
   725
                 1 == attr->attr_info.length,
sl@0
   726
                 ATTR_ERROR_INVALID_TYPE);
sl@0
   727
    COND_FAIL_NR(aContext, !attr->attr_info.readonly, ATTR_ERROR_ACCESS_DENIED);
sl@0
   728
sl@0
   729
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   730
sl@0
   731
    attr->attr_info.dirty = 1;
sl@0
   732
sl@0
   733
    switch (attr->attr_info.type) {
sl@0
   734
        case AT_FLOAT: {
sl@0
   735
            attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
sl@0
   736
            break;
sl@0
   737
        }
sl@0
   738
sl@0
   739
        case AT_INTEGER:
sl@0
   740
        case AT_BOOLEAN: {
sl@0
   741
            attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = aValue;
sl@0
   742
            break;
sl@0
   743
        }
sl@0
   744
sl@0
   745
        default: {
sl@0
   746
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   747
            break;
sl@0
   748
        }
sl@0
   749
    }
sl@0
   750
}
sl@0
   751
sl@0
   752
/*
sl@0
   753
 * \brief
sl@0
   754
 *
sl@0
   755
 * \param aContext
sl@0
   756
 * \param aName
sl@0
   757
 * \param aValue
sl@0
   758
 *
sl@0
   759
 * \return
sl@0
   760
 */
sl@0
   761
OWF_API_CALL void
sl@0
   762
OWF_Attribute_SetValuef(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   763
                        OWFint aName,
sl@0
   764
                        OWFfloat aValue)
sl@0
   765
{
sl@0
   766
    OWFint                 index = 0;
sl@0
   767
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   768
sl@0
   769
    COND_FAIL_NR_NS(aContext);
sl@0
   770
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   771
    CHECK_BAD_NR(aContext, aName);
sl@0
   772
sl@0
   773
sl@0
   774
    index = aName - aContext->range_start;
sl@0
   775
    attr = &aContext->attributes[index];
sl@0
   776
sl@0
   777
    COND_FAIL_NR(aContext,
sl@0
   778
                 1 == attr->attr_info.length,
sl@0
   779
                 ATTR_ERROR_INVALID_TYPE);
sl@0
   780
    COND_FAIL_NR(aContext,
sl@0
   781
                 !attr->attr_info.readonly,
sl@0
   782
                 ATTR_ERROR_ACCESS_DENIED);
sl@0
   783
sl@0
   784
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   785
sl@0
   786
    attr->attr_info.dirty = 1;
sl@0
   787
sl@0
   788
    switch (attr->attr_info.type) {
sl@0
   789
        case AT_FLOAT: {
sl@0
   790
            attr->attr_value[WORKING_ATTR_VALUE_INDEX].float_value[0] = aValue;
sl@0
   791
            break;
sl@0
   792
        }
sl@0
   793
sl@0
   794
        case AT_INTEGER:
sl@0
   795
        case AT_BOOLEAN: {
sl@0
   796
            attr->attr_value[WORKING_ATTR_VALUE_INDEX].int_value[0] = floor(aValue);
sl@0
   797
            break;
sl@0
   798
        }
sl@0
   799
sl@0
   800
        default: {
sl@0
   801
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   802
            break;
sl@0
   803
        }
sl@0
   804
    }
sl@0
   805
}
sl@0
   806
sl@0
   807
/*
sl@0
   808
 * \brief
sl@0
   809
 *
sl@0
   810
 * \param
sl@0
   811
 * \param
sl@0
   812
 * \param
sl@0
   813
 *
sl@0
   814
 * \return
sl@0
   815
 */
sl@0
   816
OWF_API_CALL void
sl@0
   817
OWF_Attribute_SetValueb(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   818
                        OWFint aName,
sl@0
   819
                        OWFboolean aValue)
sl@0
   820
{
sl@0
   821
    OWF_Attribute_SetValuei(aContext, aName, (OWFint) aValue);
sl@0
   822
}
sl@0
   823
sl@0
   824
/*
sl@0
   825
 * \brief
sl@0
   826
 *
sl@0
   827
 * \param
sl@0
   828
 * \param
sl@0
   829
 * \param
sl@0
   830
 *
sl@0
   831
 * \return
sl@0
   832
 */
sl@0
   833
OWF_API_CALL void
sl@0
   834
OWF_Attribute_SetValueiv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   835
                         OWFint aName,
sl@0
   836
                         OWFint aLength,
sl@0
   837
                         const OWFint* aValue)
sl@0
   838
{
sl@0
   839
    OWFint                 index = 0;
sl@0
   840
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   841
    OWFint                 count = 0;
sl@0
   842
sl@0
   843
    COND_FAIL_NR_NS(aContext);
sl@0
   844
    COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   845
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   846
    CHECK_BAD_NR(aContext, aName);
sl@0
   847
sl@0
   848
    index = aName - aContext->range_start;
sl@0
   849
    attr = &aContext->attributes[index];
sl@0
   850
/*
sl@0
   851
    COND_FAIL_NR(aContext,
sl@0
   852
               attr->attr_info.length >= 1,
sl@0
   853
               ATTR_ERROR_INVALID_TYPE);
sl@0
   854
*/
sl@0
   855
    COND_FAIL_NR(aContext,
sl@0
   856
                 aLength > 0 && aLength <= attr->attr_info.length,
sl@0
   857
                 ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   858
sl@0
   859
    COND_FAIL_NR(aContext,
sl@0
   860
                 !attr->attr_info.readonly,
sl@0
   861
                 ATTR_ERROR_ACCESS_DENIED);
sl@0
   862
sl@0
   863
    count = min(aLength, attr->attr_info.length);
sl@0
   864
sl@0
   865
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   866
sl@0
   867
    switch (attr->attr_info.type) {
sl@0
   868
        case AT_FLOAT: {
sl@0
   869
            OWFint i = 0;
sl@0
   870
            OWFfloat* v = attr->attr_value[1].float_value;
sl@0
   871
            for (i = 0; i < count; i++) {
sl@0
   872
                v[i] = floor(aValue[i]);
sl@0
   873
            }
sl@0
   874
            break;
sl@0
   875
        }
sl@0
   876
sl@0
   877
        case AT_BOOLEAN:
sl@0
   878
        case AT_INTEGER: {
sl@0
   879
            memcpy(attr->attr_value[1].int_value,
sl@0
   880
                   aValue,
sl@0
   881
                   count * attr->attr_info.size);
sl@0
   882
            break;
sl@0
   883
        }
sl@0
   884
sl@0
   885
        default: {
sl@0
   886
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   887
            break;
sl@0
   888
        }
sl@0
   889
    }
sl@0
   890
    aContext->attributes[index].attr_info.dirty = 1;
sl@0
   891
}
sl@0
   892
sl@0
   893
/*
sl@0
   894
 * \brief
sl@0
   895
 *
sl@0
   896
 * \param
sl@0
   897
 * \param
sl@0
   898
 * \param
sl@0
   899
 *
sl@0
   900
 * \return
sl@0
   901
 */
sl@0
   902
OWF_API_CALL void
sl@0
   903
OWF_Attribute_SetValuefv(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   904
                         OWFint aName,
sl@0
   905
                         OWFint aLength,
sl@0
   906
                         const OWFfloat* aValue)
sl@0
   907
{
sl@0
   908
    OWFint                 index = 0;
sl@0
   909
    OWF_ATTRIBUTE*          attr = NULL;
sl@0
   910
    OWFint                 count = 0;
sl@0
   911
sl@0
   912
    COND_FAIL_NR_NS(aContext);
sl@0
   913
    COND_FAIL_NR(aContext, aValue, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   914
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
   915
    CHECK_BAD_NR(aContext, aName);
sl@0
   916
sl@0
   917
    index = aName - aContext->range_start;
sl@0
   918
    attr = &aContext->attributes[index];
sl@0
   919
sl@0
   920
/*
sl@0
   921
    COND_FAIL_NR(aContext,
sl@0
   922
               attr->attr_info.length >= 1,
sl@0
   923
               ATTR_ERROR_INVALID_TYPE);
sl@0
   924
*/
sl@0
   925
sl@0
   926
    COND_FAIL_NR(aContext,
sl@0
   927
                 aLength > 0 && aLength <= attr->attr_info.length,
sl@0
   928
                 ATTR_ERROR_INVALID_ARGUMENT);
sl@0
   929
sl@0
   930
    COND_FAIL_NR(aContext,
sl@0
   931
                 !attr->attr_info.readonly,
sl@0
   932
                 ATTR_ERROR_ACCESS_DENIED);
sl@0
   933
sl@0
   934
    count = min(aLength, attr->attr_info.length);
sl@0
   935
sl@0
   936
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
   937
sl@0
   938
    switch (attr->attr_info.type) {
sl@0
   939
        case AT_FLOAT: {
sl@0
   940
            memcpy(attr->attr_value[1].float_value,
sl@0
   941
                   aValue,
sl@0
   942
                   count * attr->attr_info.size);
sl@0
   943
            break;
sl@0
   944
        }
sl@0
   945
sl@0
   946
        case AT_BOOLEAN:
sl@0
   947
        case AT_INTEGER: {
sl@0
   948
            OWFint i;
sl@0
   949
            OWFint* v = attr->attr_value[1].int_value;
sl@0
   950
            for (i = 0; i < count; i++) {
sl@0
   951
                 v[i] = floor(aValue[i]);
sl@0
   952
            }
sl@0
   953
            break;
sl@0
   954
        }
sl@0
   955
sl@0
   956
        default: {
sl@0
   957
            SET_ERROR(aContext, ATTR_ERROR_INVALID_TYPE);
sl@0
   958
            break;
sl@0
   959
        }
sl@0
   960
    }
sl@0
   961
    aContext->attributes[index].attr_info.dirty = 1;
sl@0
   962
}
sl@0
   963
sl@0
   964
static OWFint OWF_Attribute_Commit(OWF_ATTRIBUTE* aAttr, 
sl@0
   965
                            OWFint aDirtyFlag, 
sl@0
   966
                            OWFint aCopyTo,
sl@0
   967
                            OWFint aCopyFrom )
sl@0
   968
    {
sl@0
   969
	OWF_ASSERT(aCopyTo >= 0);
sl@0
   970
	OWF_ASSERT(aCopyTo < NUM_ATTR_VALUE_COPIES);
sl@0
   971
	OWF_ASSERT(aCopyFrom >= 0);
sl@0
   972
	OWF_ASSERT(aCopyFrom < NUM_ATTR_VALUE_COPIES);
sl@0
   973
    /* if type is undefined, it means there're gaps in the attribute
sl@0
   974
       range (e.g. reservations for future use and such.) ignore them. */
sl@0
   975
    if (aAttr->attr_info.type != AT_UNDEFINED && aDirtyFlag) 
sl@0
   976
        {
sl@0
   977
        /* poor-man's commit */
sl@0
   978
        memcpy(aAttr->attr_value[aCopyTo].gen_ptr,
sl@0
   979
                aAttr->attr_value[aCopyFrom].gen_ptr,
sl@0
   980
                aAttr->attr_info.size * aAttr->attr_info.length);
sl@0
   981
        return 0;
sl@0
   982
        }
sl@0
   983
    else
sl@0
   984
        {
sl@0
   985
        return aDirtyFlag;
sl@0
   986
        }
sl@0
   987
    }
sl@0
   988
sl@0
   989
sl@0
   990
OWF_API_CALL void
sl@0
   991
OWF_AttributeList_Commit(OWF_ATTRIBUTE_LIST* aContext,
sl@0
   992
                     OWFint aStart,
sl@0
   993
                     OWFint aEnd,
sl@0
   994
		     OWFint aCopyTo )
sl@0
   995
{
sl@0
   996
    OWFint                 index = 0;
sl@0
   997
    /* Attribute commit works like the element list commit
sl@0
   998
     * by forward-copying the "working" attributes to the snapshot  
sl@0
   999
     * during client invoked commit,
sl@0
  1000
     * then copying the snapshot to the commited scene during the docommit job.
sl@0
  1001
     * This requires the same wait-for-the-previous-commit-job strategy used in the element commit.
sl@0
  1002
     * Could in future use copy-back technique to avoid having to wait substantially, 
sl@0
  1003
     * in which case the index of the working attribute set would switch after each invoked commit,
sl@0
  1004
     * instead of being a constant.
sl@0
  1005
     *
sl@0
  1006
     * The same number of copies would still need to take place  
sl@0
  1007
     * but would not need exclusive access to the list.
sl@0
  1008
     */
sl@0
  1009
sl@0
  1010
    COND_FAIL_NR_NS(aContext);
sl@0
  1011
    COND_FAIL_NR(aContext, aStart <= aEnd, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
  1012
    COND_FAIL_NR(aContext, aContext->attributes, ATTR_ERROR_INVALID_CONTEXT);
sl@0
  1013
    CHECK_BAD_NR(aContext, aStart);
sl@0
  1014
    CHECK_BAD_NR(aContext, aEnd);
sl@0
  1015
sl@0
  1016
    switch (aCopyTo)
sl@0
  1017
        {
sl@0
  1018
        case COMMITTED_ATTR_VALUE_INDEX: /* Used in composition thread to set displayed scene attributes */
sl@0
  1019
            for (index = aStart; index <= aEnd; index++) 
sl@0
  1020
                {
sl@0
  1021
                OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
sl@0
  1022
                attr->attr_info.dirtysnapshot=
sl@0
  1023
                    OWF_Attribute_Commit(attr,attr->attr_info.dirtysnapshot,
sl@0
  1024
                            COMMITTED_ATTR_VALUE_INDEX,SNAPSHOT_ATTR_VALUE_INDEX);
sl@0
  1025
                }
sl@0
  1026
            break;
sl@0
  1027
        case SNAPSHOT_ATTR_VALUE_INDEX: /* Used in API threads to make a snapshot of the client attributes */
sl@0
  1028
             for (index = aStart; index <= aEnd; index++) 
sl@0
  1029
                 {
sl@0
  1030
                 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
sl@0
  1031
                 OWFuint oldDirty=attr->attr_info.dirty;
sl@0
  1032
                 attr->attr_info.dirtysnapshot=oldDirty;
sl@0
  1033
                 attr->attr_info.dirty=
sl@0
  1034
                     OWF_Attribute_Commit(attr,oldDirty,
sl@0
  1035
                             SNAPSHOT_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
sl@0
  1036
                 }
sl@0
  1037
             break;
sl@0
  1038
        case WORKING_ATTR_VALUE_INDEX:   /* Used in initialisation to copy displayed attributes to client copies */
sl@0
  1039
             for (index = aStart; index <= aEnd; index++) 
sl@0
  1040
                 {
sl@0
  1041
                 OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
sl@0
  1042
                 OWF_Attribute_Commit(attr,!attr->attr_info.readonly,
sl@0
  1043
                         WORKING_ATTR_VALUE_INDEX,COMMITTED_ATTR_VALUE_INDEX);
sl@0
  1044
                 }
sl@0
  1045
             break;
sl@0
  1046
	case COMMIT_ATTR_DIRECT_FROM_WORKING: /* Used in WFD to commit new working values directly in 1 step. */
sl@0
  1047
            for (index = aStart; index <= aEnd; index++) 
sl@0
  1048
                {
sl@0
  1049
                OWF_ATTRIBUTE* attr = &aContext->attributes[index - aContext->range_start];
sl@0
  1050
                attr->attr_info.dirty=
sl@0
  1051
                    OWF_Attribute_Commit(attr,attr->attr_info.dirty,
sl@0
  1052
                            COMMITTED_ATTR_VALUE_INDEX,WORKING_ATTR_VALUE_INDEX);
sl@0
  1053
                }
sl@0
  1054
            break;
sl@0
  1055
	default:
sl@0
  1056
			COND_FAIL_NR(aContext, 0, ATTR_ERROR_INVALID_ARGUMENT);
sl@0
  1057
          }
sl@0
  1058
    
sl@0
  1059
    SET_ERROR(aContext, ATTR_ERROR_NONE);
sl@0
  1060
}
sl@0
  1061
sl@0
  1062
#ifdef __cplusplus
sl@0
  1063
}
sl@0
  1064
#endif