os/graphics/graphicscomposition/openwfcompositionengine/composition/src/wfcdevice.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.
     1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
     2  * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
     3  *
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     5  * copy of this software and/or associated documentation files (the
     6  * "Materials"), to deal in the Materials without restriction, including
     7  * without limitation the rights to use, copy, modify, merge, publish,
     8  * distribute, sublicense, and/or sell copies of the Materials, and to
     9  * permit persons to whom the Materials are furnished to do so, subject to
    10  * the following conditions:
    11  *
    12  * The above copyright notice and this permission notice shall be included
    13  * in all copies or substantial portions of the Materials.
    14  *
    15  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    21  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
    22  */
    23 /*! \ingroup wfc
    24  *  \file wfcdevice.c
    25  *
    26  *  \brief SI Device handling
    27  */
    28 
    29 
    30 #include <stdio.h>
    31 #include <string.h>
    32 #include <stdlib.h>
    33 
    34 #include "wfcdevice.h"
    35 #include "wfcelement.h"
    36 #include "wfccontext.h"
    37 #include "wfcimageprovider.h"
    38 
    39 #include "owfarray.h"
    40 #include "owfmemory.h"
    41 #include "owfmutex.h"
    42 #include "owfscreen.h"
    43 #include "owftypes.h"
    44 #include "owfobject.h"
    45 #include "owfnativestream.h"
    46 #include "owfnotifications.h"
    47 #include "owfdebug.h"
    48 
    49 #ifdef __cplusplus
    50 extern "C" {
    51 #endif
    52 
    53 #define MAX_ATTRIBUTES      32
    54 
    55 #define FAIL_IF(c,e)        if (c) { LEAVE(0); return e; }
    56 
    57 #define FIRST_DEVICE_HANDLE 1000
    58 
    59 PHYSICAL_DEVICE gPhyDevice;
    60 
    61 
    62 /*-------------------------------------------------------------------------*//*!
    63  *  \internal
    64  *
    65  *  Initialize devices with default parameters.
    66  *//*-------------------------------------------------------------------------*/
    67 OWF_API_CALL void
    68 WFC_Devices_Initialize()
    69 {
    70     static WFCboolean initialised=WFC_FALSE;
    71     if (!initialised)
    72     {
    73         OWF_Array_Initialize(&(gPhyDevice.iDeviceInstanceArray));
    74         gPhyDevice.gDeviceHandleID = 0;
    75         initialised=WFC_TRUE;
    76     }
    77 }
    78 
    79 /*---------------------------------------------------------------------------
    80  *
    81  *
    82  *----------------------------------------------------------------------------*/
    83 OWF_API_CALL WFCint
    84 WFC_Devices_GetIds(WFCint* idList,
    85                    WFCint listCapacity,
    86                    const WFCint* filterList)
    87 {
    88 
    89 /* We assume there is only one physical device and
    90  * all screens are supported by this device */
    91 
    92     WFCint                  screenNumber = OWF_RESERVED_BAD_SCREEN_NUMBER,
    93                             n = MAX_ATTRIBUTES,
    94                             i = 0;
    95     WFCboolean              hasFilter;
    96 
    97     hasFilter = (filterList && (*filterList != WFC_NONE)) ?
    98                 WFC_TRUE :
    99                 WFC_FALSE;
   100 
   101     /* handle filter list, if given */
   102     if (hasFilter)
   103     {
   104         /* scan filter list (up to 32 attributes) */
   105         while (n > 0 && WFC_NONE != filterList[0])
   106         {
   107             switch (filterList[0])
   108             {
   109                 case WFC_DEVICE_FILTER_SCREEN_NUMBER:
   110                     if (screenNumber!=OWF_RESERVED_BAD_SCREEN_NUMBER && screenNumber!=filterList[1])
   111                          {
   112                          /* invalid repeated filter on screen number */
   113                           return 0;
   114                          }
   115                     screenNumber = filterList[1];
   116                     if (!OWF_Screen_Valid(screenNumber))
   117                     {
   118                         /* invalid screen number */
   119                         return 0;
   120                     }
   121                     break;
   122 
   123                 case WFC_NONE:
   124                     n = 0;
   125                     break;
   126 
   127                 default:
   128                     /* EARLY EXIT - invalid attribute */
   129                     return 0;
   130             }
   131 
   132             /* Move pointer to next key-value pair */
   133             filterList += 2;
   134             n--;
   135         }
   136     }
   137 
   138     /* Return number of available devices */
   139     if (NULL == idList && !hasFilter) {
   140         return 1;
   141     }
   142 
   143     for (i = 0, n = 0; i < 1 && listCapacity >= 0; i++) {
   144         /* idList might be NULL when querying all devices w/
   145          * screen number in filter list */
   146         if (idList && n < listCapacity)
   147         {
   148             idList[n] = OWF_SUPPORTED_DEVICE_ID;
   149         }
   150 
   151         n++;
   152     }
   153 
   154     return n;
   155 }
   156 
   157 
   158 /*---------------------------------------------------------------------------
   159  *  Create instance of a device whose ID
   160  *  matches deviceId
   161  *
   162  *  \param deviceId ID of the device to create. Must be WFC_DEFAULT_DEVICE_ID
   163  *  or some other valid device ID (returned by Devices_GetIds)
   164  *
   165  *  \return Handle to created device or WFC_INVALID_HANDLE
   166  *
   167  *----------------------------------------------------------------------------*/
   168 OWF_API_CALL WFCint
   169 WFC_Device_Create(WFCint deviceId)
   170 {
   171 	WFC_DEVICE *dev = NULL;
   172 	
   173     ENTER(WFC_Device_Create);
   174     
   175     WFC_Devices_Initialize();
   176 
   177     if (deviceId != WFC_DEFAULT_DEVICE_ID && deviceId != OWF_SUPPORTED_DEVICE_ID)
   178     {
   179         return WFC_INVALID_HANDLE;
   180     }
   181     
   182     dev = DEVICE(xalloc(1,sizeof(WFC_DEVICE)));
   183     if (dev == NULL)
   184     {
   185     	return WFC_INVALID_HANDLE;
   186     }
   187     
   188     dev->handle = FIRST_DEVICE_HANDLE + (gPhyDevice.gDeviceHandleID)++;
   189     dev->deviceId = deviceId;
   190     dev->latestUnreadError = WFC_ERROR_NONE;
   191     dev->mutex = NULL;
   192     OWF_Array_Initialize(&dev->contexts);
   193     OWF_Array_Initialize(&dev->providers);
   194     OWF_Array_Initialize(&dev->elements);
   195 
   196     if (!OWF_Array_AppendItem(&(gPhyDevice.iDeviceInstanceArray), dev))
   197         {
   198         xfree(dev);
   199         return WFC_INVALID_HANDLE;
   200         }
   201 
   202     LEAVE(WFC_Device_Create);
   203 
   204     return dev->handle;
   205 }
   206 
   207 /*---------------------------------------------------------------------------
   208  *  Set error code for device. Obs! In case the previous
   209  *  error code hasn't been read from the device, this function
   210  *  does nothing; the new error is set only if "current" error
   211  *  is none.
   212  *
   213  *  \param dev Device object
   214  *  \param code Error to set
   215  *
   216  *----------------------------------------------------------------------------*/
   217 OWF_API_CALL void OWF_APIENTRY
   218 WFC_Device_SetError(WFCDevice dev,
   219                     WFCErrorCode code)
   220 {
   221 #ifdef DEBUG_LOG
   222     static char* const      errmsg[] =
   223                             {
   224                             "WFC_ERROR_NONE",
   225                             "WFC_ERROR_OUT_OF_MEMORY",
   226                             "WFC_ERROR_ILLEGAL_ARGUMENT",
   227                             "WFC_ERROR_UNSUPPORTED",
   228                             "WFC_ERROR_BAD_ATTRIBUTE",
   229                             "WFC_ERROR_IN_USE",
   230                             "WFC_ERROR_BUSY",
   231                             "WFC_ERROR_BAD_DEVICE",
   232                             "WFC_ERROR_BAD_HANDLE",
   233                             "WFC_ERROR_INCONSISTENCY",
   234                             };
   235 #endif
   236     
   237     WFC_DEVICE* device = WFC_Device_FindByHandle(dev);
   238     if (WFC_INVALID_HANDLE == device)
   239     {
   240         /* Invalid device handle. Nothing we can do about it so return. */
   241         return;
   242     }
   243 
   244     if (!device->mutex)
   245     {
   246         OWF_Mutex_Init(&device->mutex);
   247     }
   248 
   249     OWF_Mutex_Lock(&device->mutex);
   250     if (code == WFC_ERROR_IN_USE)
   251         {
   252         code=WFC_ERROR_IN_USE;
   253         }
   254     if (WFC_INVALID_HANDLE != device) {
   255         if (WFC_ERROR_NONE == device->latestUnreadError &&
   256             code != device->latestUnreadError)
   257         {
   258 #ifdef DEBUG_LOG
   259              char* const msg = errmsg[code > WFC_ERROR_NONE ?
   260                     code - WFC_ERROR_OUT_OF_MEMORY + 1 : 0];
   261              (void)msg; //always reference to avoid warning
   262 #endif
   263 
   264             DPRINT(("setError(dev = %08x, err = %08x)", dev, code));
   265             DPRINT(("  error set to = %04x (%s)", (OWFuint16) code, msg));
   266 
   267             device->latestUnreadError = code;
   268         }
   269     }
   270 
   271     OWF_Mutex_Unlock(&device->mutex);
   272 }
   273 
   274 /*---------------------------------------------------------------------------
   275  *  Read and reset last error code from device.
   276  *
   277  *  \param device Device object
   278  *
   279  *  \return WFCErrorCode
   280  *----------------------------------------------------------------------------*/
   281 OWF_API_CALL WFCErrorCode
   282 WFC_Device_GetError(WFC_DEVICE* device)
   283 {
   284     WFCErrorCode            err;
   285 
   286     OWF_ASSERT(device);
   287 
   288     err = device->latestUnreadError;
   289     device->latestUnreadError = WFC_ERROR_NONE;
   290     return err;
   291 }
   292 
   293 /*---------------------------------------------------------------------------
   294  *  Find device object by handle
   295  *
   296  *  \param dev Device handle
   297  *
   298  *  \return Matching device object or NULL
   299  *----------------------------------------------------------------------------*/
   300 OWF_API_CALL WFC_DEVICE*
   301 WFC_Device_FindByHandle(WFCDevice dev)
   302 {
   303     WFCint i = 0, length = 0;
   304     WFC_DEVICE* pDevice = NULL;
   305     
   306     if (dev == WFC_INVALID_HANDLE)
   307     {
   308         return NULL;
   309     }
   310     
   311     WFC_Devices_Initialize();
   312     
   313     length = gPhyDevice.iDeviceInstanceArray.length;
   314     for (i = 0; i < length; ++i)
   315         {
   316         pDevice = DEVICE(OWF_Array_GetItemAt(&(gPhyDevice.iDeviceInstanceArray), i));
   317         if (pDevice->handle == dev)
   318             {
   319             return pDevice;
   320             }
   321         }
   322     return NULL;
   323 }
   324 
   325 /*---------------------------------------------------------------------------
   326  *  Get device attribute
   327  *
   328  *  \param device Device
   329  *  \param attrib Attribute name
   330  *  \param value Pointer to where the value should be saved
   331  *
   332  *  \return WFCErrorCode
   333  *----------------------------------------------------------------------------*/
   334 OWF_API_CALL WFCErrorCode
   335 WFC_Device_GetAttribi(WFC_DEVICE* device,
   336                       WFCDeviceAttrib attrib,
   337                       WFCint* value)
   338 {
   339     WFCErrorCode            result = WFC_ERROR_NONE;
   340 
   341     OWF_ASSERT(device);
   342 
   343     switch (attrib)
   344     {
   345         case WFC_DEVICE_CLASS:
   346         {
   347             *value = WFC_DEVICE_CLASS_FULLY_CAPABLE;
   348             break;
   349         }
   350         case WFC_DEVICE_ID:
   351         {
   352             *value = device->deviceId;
   353             break;
   354         }
   355         default:
   356         {
   357             result = WFC_ERROR_BAD_ATTRIBUTE;
   358         }
   359     }
   360     return result;
   361 }
   362 
   363 /*[][][][] CONTEXTS  [][][][][][][][][][][][][][][][][][][][][][][][][][][][]*/
   364 
   365 /*---------------------------------------------------------------------------
   366  *  Create context on device
   367  *
   368  *  \param device Device
   369  *  \param stream Target stream for context
   370  *  \param type Context type
   371  *
   372  *  \return New context
   373  *----------------------------------------------------------------------------*/
   374 OWF_API_CALL WFC_CONTEXT*
   375 WFC_Device_CreateContext(WFC_DEVICE* device,
   376                          OWFNativeStreamType stream,
   377                          WFCContextType type,
   378                          WFCint screenNum)
   379 {
   380     WFC_CONTEXT*            context;
   381 
   382     ENTER(WFC_Device_CreateContext);
   383 
   384     OWF_ASSERT(device);
   385 
   386     context = WFC_Context_Create(device, stream, type, screenNum);
   387     if (context)
   388     {
   389         if (!OWF_Array_AppendItem(&device->contexts, context))
   390         {
   391             DESTROY(context);
   392         }
   393     }
   394     LEAVE(WFC_Device_CreateContext);
   395 
   396     return context;
   397 }
   398 
   399 /*---------------------------------------------------------------------------
   400  *  Destroy context from device
   401  *----------------------------------------------------------------------------*/
   402 OWF_API_CALL WFCErrorCode
   403 WFC_Device_DestroyContext(WFC_DEVICE* device,
   404                           WFCContext context)
   405 {
   406     WFCint                  i;
   407     WFCErrorCode            result = WFC_ERROR_BAD_HANDLE;
   408     ENTER(WFC_Device_DestroyContext);
   409 
   410     OWF_ASSERT(device);
   411 
   412     DPRINT(("WFC_Device_DestroyContext(context = %d)", context));
   413 
   414     for (i = 0; i < device->contexts.length; i++)
   415     {
   416         WFC_CONTEXT*        ctmp;
   417 
   418         ctmp = (WFC_CONTEXT*) OWF_Array_GetItemAt(&device->contexts, i);
   419         if (ctmp->handle == context)
   420         {
   421             WFC_CONTEXT*    context;
   422 
   423             context = CONTEXT(OWF_Array_RemoveItemAt(&device->contexts, i));
   424             DPRINT(("  Shutting down context %d", context->handle));
   425             WFC_Context_Shutdown(context);
   426             DESTROY(context);
   427             result = WFC_ERROR_NONE;
   428             break;
   429         }
   430     }
   431 
   432     DPRINT((""));
   433 
   434     DPRINT(("-------------------------------------------------------"));
   435     DPRINT(("Device statistics after context destruction:"));
   436     DPRINT(("  Contexts: %d", device->contexts.length));
   437     DPRINT(("  Elements: %d", device->elements.length));
   438     DPRINT(("  Image providers: %d", device->providers.length));
   439      DPRINT(("-------------------------------------------------------"));
   440     LEAVE(WFC_Device_DestroyContext);
   441 
   442     return result;
   443 }
   444 
   445 /*---------------------------------------------------------------------------
   446  *  Destroy all device's contexts
   447  *
   448  *  \param device Device object
   449  *----------------------------------------------------------------------------*/
   450 OWF_API_CALL void
   451 WFC_Device_DestroyContexts(WFC_DEVICE* device)
   452 {
   453     WFCint                  i;
   454 
   455     ENTER(WFC_Device_DestroyContexts);
   456 
   457     for (i = 0; i < device->contexts.length; i++)
   458     {
   459         WFC_CONTEXT*        context;
   460 
   461         context = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
   462         WFC_Context_Shutdown(context);
   463 
   464         DESTROY(context);
   465     }
   466     OWF_Array_Destroy(&device->contexts);
   467 
   468     LEAVE(WFC_Device_DestroyContexts);
   469 }
   470 
   471 /*---------------------------------------------------------------------------
   472  *  Find context context object by handle
   473  *
   474  *  \param device Device
   475  *  \param context Context handle
   476  *
   477  *  \return Corresponding context object or NULL
   478  *  if handle is invalid.
   479  *----------------------------------------------------------------------------*/
   480 OWF_API_CALL WFC_CONTEXT*
   481 WFC_Device_FindContext(WFC_DEVICE* device,
   482                        WFCContext context)
   483 {
   484     WFCint                  i;
   485     WFC_CONTEXT*            result = NULL;
   486 
   487     ENTER(WFC_Device_FindContext);
   488 
   489     FAIL_IF(NULL == device, NULL);
   490 
   491     for (i = 0; i < device->contexts.length; i++)
   492     {
   493         WFC_CONTEXT*        ctmp;
   494 
   495         ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
   496         if (ctmp->handle == context)
   497         {
   498             result = ctmp;
   499             break;
   500         }
   501     }
   502     LEAVE(WFC_Device_FindContext);
   503 
   504     return result;
   505 }
   506 /*[][][][] ELEMENTS  [][][][][][][][][][][][][][][][][][][][][][][][][][][][]*/
   507 
   508 /*---------------------------------------------------------------------------
   509  *  Create new element
   510  *
   511  *  \param device
   512  *  \param context
   513  *
   514  *  \return New element or NULL
   515  *----------------------------------------------------------------------------*/
   516 OWF_API_CALL WFC_ELEMENT*
   517 WFC_Device_CreateElement(WFC_DEVICE* device, WFC_CONTEXT* context)
   518 {
   519     WFC_ELEMENT*        element=NULL;
   520 
   521     ENTER(WFC_Device_CreateElement);
   522 
   523     FAIL_IF(NULL == device || NULL == context, NULL);
   524     if (WFC_Context_IncreaseClientElementCount(context)>0)
   525     {
   526         element = WFC_Element_Create(context);
   527         if (!element || !OWF_Array_AppendItem(&device->elements, element))
   528         {
   529             DPRINT(("WFC_Device_CreateElement: couldn't create element"));
   530             WFC_Context_DecreaseClientElementCount(context);
   531             if (element)
   532                 {
   533                 WFC_Element_Destroy(element);
   534                 }
   535             element = NULL;
   536         }
   537         else
   538         {
   539             /* #4585: statement moved to else block */
   540             DPRINT(("  Created element; handle = %d", element->handle));
   541         }
   542     }
   543     LEAVE(WFC_Device_CreateElement);
   544 
   545     return element;
   546 }
   547 
   548 /*---------------------------------------------------------------------------
   549  *  Destroy element
   550  *
   551  *  \param device
   552  *  \param element
   553  *----------------------------------------------------------------------------*/
   554 OWF_API_CALL WFCErrorCode
   555 WFC_Device_DestroyElement(WFC_DEVICE* device,
   556                           WFCElement element)
   557 {
   558     WFCint                  i;
   559     WFCErrorCode            result = WFC_ERROR_BAD_HANDLE;
   560 
   561     ENTER(WFC_Device_DestroyElement);
   562 
   563     FAIL_IF(NULL == device, WFC_ERROR_BAD_HANDLE);
   564     DPRINT(("destroying element %d", element));
   565 
   566     for (i = 0; i < device->elements.length; i++)
   567     {
   568         WFC_ELEMENT*        object;
   569 
   570         object = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
   571         DPRINT(("  element %d = %d", i, object->handle));
   572         if (object->handle == element)
   573         {
   574             WFC_Context_RemoveElement(CONTEXT(object->context), element);
   575 
   576             WFC_Context_DecreaseClientElementCount(object->context);
   577             OWF_Array_RemoveItemAt(&device->elements, i);
   578             WFC_Element_Destroy(object);
   579             result = WFC_ERROR_NONE;
   580             break;
   581         }
   582     }
   583     LEAVE(WFC_Device_DestroyElement);
   584     return result;
   585 }
   586 
   587 /*---------------------------------------------------------------------------
   588  *  Destroy all elements from device
   589  *
   590  *  \param device Device
   591  *----------------------------------------------------------------------------*/
   592 OWF_API_CALL void
   593 WFC_Device_DestroyElements(WFC_DEVICE* device)
   594 {
   595     WFCint                  i;
   596 
   597     ENTER(WFC_Device_DestroyElements);
   598 
   599     OWF_ASSERT(device);
   600 
   601     for (i = 0; i < device->elements.length; i++)
   602     {
   603         WFC_ELEMENT*        etemp;
   604 
   605         etemp = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
   606         WFC_Element_Destroy(etemp);
   607     }
   608     OWF_Array_Destroy(&device->elements);
   609 
   610     LEAVE(WFC_Device_DestroyElements);
   611 }
   612 
   613 /*---------------------------------------------------------------------------
   614  *  Find element by handle
   615  *
   616  *  \param device Device
   617  *  \param el Element handle
   618  *
   619  *  \return Element object
   620  *----------------------------------------------------------------------------*/
   621 OWF_API_CALL WFC_ELEMENT*
   622 WFC_Device_FindElement(WFC_DEVICE* device,
   623                        WFCElement el)
   624 {
   625     WFC_ELEMENT*            result = WFC_INVALID_HANDLE;
   626     WFCint                  i;
   627 
   628     FAIL_IF(NULL == device, NULL);
   629 
   630     for (i = 0; i < device->elements.length; i++)
   631     {
   632         WFC_ELEMENT*        element;
   633         element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
   634 
   635         if (element->handle == el)
   636         {
   637             result = element;
   638             break;
   639         }
   640 
   641     }
   642     return result;
   643 }
   644 
   645 /*---------------------------------------------------------------------------
   646  *  Set element integer vector attribute
   647  *
   648  *  \param device Device
   649  *  \param element Element handle
   650  *  \param attrib Attribute name
   651  *  \param count Attribute value vector length (1 for scalar attribute)
   652  *  \param values Pointer to values
   653  *
   654  *  \return WFCErrorCode: WFC_ERROR_BAD_ATTRIBUTE if attribute name is invalid;
   655  *  WFC_ERROR_INVALID_ARGUMENT if values is NULL or if the count doesn't match
   656  *  the attribute's size; WFC_ERROR_BAD_HANDLE if element handle is invalid.
   657  *----------------------------------------------------------------------------*/
   658 OWF_API_CALL WFCErrorCode
   659 WFC_Device_SetElementAttribiv(WFC_DEVICE* device,
   660                               WFCElement element,
   661                               WFCElementAttrib attrib,
   662                               WFCint count,
   663                               const WFCint* values)
   664 {
   665     WFC_ELEMENT*            object;
   666 
   667     OWF_ASSERT(device);
   668 
   669     object = WFC_Device_FindElement(device, element);
   670     FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
   671     return WFC_Element_SetAttribiv(object, attrib, count, values);
   672 }
   673 
   674 /*---------------------------------------------------------------------------
   675  *
   676  *
   677  *----------------------------------------------------------------------------*/
   678 OWF_API_CALL WFCErrorCode
   679 WFC_Device_SetElementAttribfv(WFC_DEVICE* device,
   680                               WFCElement element,
   681                               WFCElementAttrib attrib,
   682                               WFCint count,
   683                               const WFCfloat* values)
   684 {
   685     WFC_ELEMENT*            object;
   686 
   687     OWF_ASSERT(device);
   688 
   689     object = WFC_Device_FindElement(device, element);
   690     FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
   691     return WFC_Element_SetAttribfv(object, attrib, count, values);
   692 }
   693 
   694 /*---------------------------------------------------------------------------
   695  *
   696  *
   697  *----------------------------------------------------------------------------*/
   698 OWF_API_CALL WFCErrorCode
   699 WFC_Device_GetElementAttribiv(WFC_DEVICE* device,
   700                               WFCElement element,
   701                               WFCElementAttrib attrib,
   702                               WFCint count,
   703                               WFCint* values)
   704 {
   705     WFC_ELEMENT*            object;
   706 
   707     OWF_ASSERT(device);
   708 
   709     object = WFC_Device_FindElement(device, element);
   710     FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
   711     return WFC_Element_GetAttribiv(object, attrib, count, values);
   712 }
   713 
   714 /*---------------------------------------------------------------------------
   715  *
   716  *
   717  *----------------------------------------------------------------------------*/
   718 OWF_API_CALL WFCErrorCode
   719 WFC_Device_GetElementAttribfv(WFC_DEVICE* device,
   720                               WFCElement element,
   721                               WFCElementAttrib attrib,
   722                               WFCint count,
   723                               WFCfloat* values)
   724 {
   725     WFC_ELEMENT*            object;
   726 
   727     OWF_ASSERT(device);
   728 
   729     object = WFC_Device_FindElement(device, element);
   730     FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
   731     return WFC_Element_GetAttribfv(object, attrib, count, values);
   732 }
   733 
   734 
   735 /*[][][][] IMAGE PROVIDERS [][][][][][][][][][][][][][][][][][][][][][][][][]*/
   736 
   737 /*---------------------------------------------------------------------------
   738  *
   739  *----------------------------------------------------------------------------*/
   740 OWF_API_CALL void
   741 WFC_Device_EnableContentNotifications(WFC_DEVICE* device,
   742                                       WFC_CONTEXT* context,
   743                                       WFCboolean enable)
   744 {
   745     WFCint                  i;
   746 
   747     OWF_ASSERT(device);
   748     OWF_ASSERT(context);
   749 
   750     context = context;
   751 
   752     for (i = 0; i < device->providers.length; i++)
   753     {
   754         WFC_IMAGE_PROVIDER* prov;
   755 
   756         prov = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
   757 
   758         owfNativeStreamEnableUpdateNotifications(prov->streamHandle,
   759                                                  enable ? OWF_TRUE : OWF_FALSE);
   760     }
   761 }
   762 
   763 /*---------------------------------------------------------------------------
   764  *
   765  *----------------------------------------------------------------------------*/
   766 static WFC_IMAGE_PROVIDER*
   767 WFC_Device_CreateImageProvider(WFC_DEVICE* device,
   768                                WFC_CONTEXT* context,
   769                                OWFNativeStreamType stream,
   770                                WFC_IMAGE_PROVIDER_TYPE type)
   771 {
   772     WFC_IMAGE_PROVIDER*         provider;
   773     WFCint						success;
   774 
   775     OWF_ASSERT(device);
   776     OWF_ASSERT(context);
   777 
   778     /* create/fetch stream-wrapper for native stream.  */
   779 
   780     /* create new image provider object associated to
   781      * native stream wrapper previously fetched */
   782     provider = WFC_ImageProvider_Create(context, stream, type);
   783     if (!provider)
   784     {
   785         return NULL;
   786     }   
   787 
   788     success = OWF_TRUE;
   789     if (OWF_Array_AppendItem(&device->providers, provider) != OWF_TRUE)
   790     {
   791         success = OWF_FALSE;
   792     }
   793 
   794     if (!success || !owfSymDeviceInitialise(provider))
   795     {
   796         OWF_Array_RemoveItem(&device->providers, provider);
   797         success = OWF_FALSE;
   798     }
   799     if (!success)
   800     {
   801         DESTROY(provider);
   802         provider = NULL;
   803     }
   804     return provider;
   805 }
   806 
   807 /*---------------------------------------------------------------------------
   808  *
   809  *----------------------------------------------------------------------------*/
   810 static WFCErrorCode
   811 WFC_Device_DestroyImageProvider(WFC_DEVICE* device,
   812                                 WFCHandle handle)
   813 {
   814     WFCint                  i;
   815     WFCErrorCode            result = WFC_ERROR_BAD_HANDLE;
   816 
   817     ENTER(WFC_Device_DestroyImageProvider);
   818 
   819     OWF_ASSERT(device);
   820 
   821     DPRINT(("  number of providers = %d", device->providers.length));
   822 
   823     for (i = 0; i < device->providers.length; i++)
   824     {
   825         WFC_IMAGE_PROVIDER* object;
   826 
   827         object = (WFC_IMAGE_PROVIDER*)OWF_Array_GetItemAt(&device->providers, i);
   828 		OWF_ASSERT(object);
   829         if (object->handle == handle)
   830         {
   831         
   832             DPRINT(("  Destroying image provider %d", handle));
   833             
   834             owfSymDeviceDestroy(device, object, i);
   835             OWF_Array_RemoveItemAt(&device->providers, i);
   836                         
   837             DESTROY(object);
   838             result = WFC_ERROR_NONE;
   839             break;
   840         }
   841     }
   842 
   843     /*
   844      *  Image provider's source content observer should be removed here,
   845      *  but on the other hand, it'll be removed when the image provider's
   846      *  source stream gets destroyed.
   847      */
   848     LEAVE(WFC_Device_DestroyImageProvider);
   849     return result;
   850 }
   851 
   852 /*---------------------------------------------------------------------------
   853  *  Destroy all image providers from device
   854  *
   855  *  \param device Device
   856  *----------------------------------------------------------------------------*/
   857 OWF_API_CALL void
   858 WFC_Device_DestroyImageProviders(WFC_DEVICE* device)
   859 {
   860     WFCint                  i;
   861 
   862     ENTER(WFC_Device_DestroyImageProviders);
   863 
   864     OWF_ASSERT(device);
   865 
   866     DPRINT(("number of providers = %d", device->providers.length));
   867 
   868     for (i = 0; i < device->providers.length; i++)
   869     {
   870         WFC_IMAGE_PROVIDER* itemp;
   871 
   872         itemp = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
   873         DESTROY(itemp);
   874     }
   875     OWF_Array_Destroy(&device->providers);
   876 
   877     LEAVE(WFC_Device_DestroyImageProviders);
   878 }
   879 
   880 /*---------------------------------------------------------------------------
   881  *
   882  *----------------------------------------------------------------------------*/
   883 OWF_API_CALL WFC_IMAGE_PROVIDER*
   884 WFC_Device_FindImageProvider(WFC_DEVICE* device,
   885                              WFCHandle handle,
   886                              WFC_IMAGE_PROVIDER_TYPE type)
   887 {
   888     WFCint                  i;
   889     WFC_IMAGE_PROVIDER*     result = WFC_INVALID_HANDLE;
   890 
   891     ENTER(WFC_Device_FindImageProvider);
   892 
   893     OWF_ASSERT(device);
   894     DPRINT(("number of providers = %d", device->providers.length));
   895 
   896     for (i = 0; i < device->providers.length; i++)
   897     {
   898         WFC_IMAGE_PROVIDER* object;
   899 
   900         object = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
   901         if (object->handle == handle && object->type == type)
   902         {
   903             result = object;
   904             break;
   905         }
   906     }
   907 
   908     LEAVE(WFC_Device_FindImageProvider);
   909 
   910     return result;
   911 }
   912 
   913 /*---------------------------------------------------------------------------
   914  *
   915  *----------------------------------------------------------------------------*/
   916 OWF_API_CALL WFC_IMAGE_PROVIDER*
   917 WFC_Device_CreateSource(WFC_DEVICE* device,
   918                         WFC_CONTEXT* context,
   919                         WFCNativeStreamType stream)
   920 {
   921     OWF_ASSERT(device);
   922     OWF_ASSERT(context);
   923     return WFC_Device_CreateImageProvider(device,
   924                                           context, stream, WFC_IMAGE_SOURCE);
   925 }
   926 
   927 /*---------------------------------------------------------------------------
   928  *
   929  *----------------------------------------------------------------------------*/
   930 OWF_API_CALL WFC_IMAGE_PROVIDER*
   931 WFC_Device_CreateMask(WFC_DEVICE* device,
   932                       WFC_CONTEXT* context,
   933                       WFCNativeStreamType stream)
   934 {
   935     OWF_ASSERT(device);
   936     OWF_ASSERT(context);
   937     return WFC_Device_CreateImageProvider(device,
   938                                           context, stream, WFC_IMAGE_MASK);
   939 }
   940 
   941 /*---------------------------------------------------------------------------
   942  *
   943  *----------------------------------------------------------------------------*/
   944 OWF_API_CALL WFCErrorCode
   945 WFC_Device_DestroySource(WFC_DEVICE* device, WFCSource source)
   946 {
   947     OWF_ASSERT(device);
   948     return WFC_Device_DestroyImageProvider(device, source);
   949 }
   950 
   951 /*---------------------------------------------------------------------------
   952  *
   953  *----------------------------------------------------------------------------*/
   954 OWF_API_CALL WFCErrorCode
   955 WFC_Device_DestroyMask(WFC_DEVICE* device, WFCMask mask)
   956 {
   957     OWF_ASSERT(device);
   958     return WFC_Device_DestroyImageProvider(device, mask);
   959 }
   960 
   961 /*---------------------------------------------------------------------------
   962  *
   963  *----------------------------------------------------------------------------*/
   964 OWF_API_CALL WFC_IMAGE_PROVIDER*
   965 WFC_Device_FindSource(WFC_DEVICE* device, WFCSource source)
   966 {
   967     OWF_ASSERT(device);
   968     return WFC_Device_FindImageProvider(device, source, WFC_IMAGE_SOURCE);
   969 }
   970 
   971 /*---------------------------------------------------------------------------
   972  *
   973  *----------------------------------------------------------------------------*/
   974 OWF_API_CALL WFC_IMAGE_PROVIDER*
   975 WFC_Device_FindMask(WFC_DEVICE* device, WFCMask mask)
   976 {
   977     OWF_ASSERT(device);
   978     return WFC_Device_FindImageProvider(device, mask, WFC_IMAGE_MASK);
   979 }
   980 
   981 /*---------------------------------------------------------------------------
   982  *  Destroy device, or rather queue it for destruction.
   983  *
   984  *  \param device Device
   985  *----------------------------------------------------------------------------*/
   986 OWF_API_CALL void
   987 WFC_Device_Destroy(WFC_DEVICE* device)
   988 {
   989     ENTER(WFC_Device_Destroy);
   990 
   991     OWF_ASSERT(device);
   992 
   993     /* release resources */
   994     WFC_Device_DestroyElements(device);
   995     WFC_Device_DestroyImageProviders(device);
   996     WFC_Device_DestroyContexts(device);
   997 
   998     OWF_Mutex_Destroy(&device->mutex);
   999     device->mutex = NULL;
  1000 
  1001     device->latestUnreadError = WFC_ERROR_NONE;
  1002     device->handle = WFC_INVALID_HANDLE;
  1003     
  1004     OWF_Array_RemoveItem(&(gPhyDevice.iDeviceInstanceArray), device);
  1005     xfree(device);
  1006     if (gPhyDevice.iDeviceInstanceArray.length == 0)
  1007         {
  1008         OWF_Array_Destroy(&(gPhyDevice.iDeviceInstanceArray));
  1009         }
  1010     LEAVE(WFC_Device_Destroy);
  1011 }
  1012 
  1013 /*---------------------------------------------------------------------------
  1014  *
  1015  *----------------------------------------------------------------------------*/
  1016 OWF_API_CALL WFCboolean
  1017 WFC_Device_StreamIsTarget(WFC_DEVICE* device,
  1018                           WFCNativeStreamType stream)
  1019 {
  1020     WFCint                  i;
  1021     WFCboolean              result = WFC_FALSE;
  1022 
  1023     OWF_ASSERT(device);
  1024 
  1025     for (i = 0; i < device->contexts.length; i++)
  1026     {
  1027         WFC_CONTEXT*        ctmp;
  1028 
  1029         ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
  1030         if (ctmp->stream == stream)
  1031         {
  1032             result = WFC_TRUE;
  1033             break;
  1034         }
  1035     }
  1036     return result;
  1037 }
  1038 
  1039 /*---------------------------------------------------------------------------
  1040  *
  1041  *----------------------------------------------------------------------------*/
  1042 OWF_API_CALL WFC_CONTEXT*
  1043 WFC_Device_FindContextByScreen(WFC_DEVICE* device,
  1044                                WFCint screenNumber)
  1045 {
  1046     WFCint                  i;
  1047     WFC_CONTEXT*            result = NULL;
  1048 
  1049     OWF_ASSERT(device);
  1050 
  1051     for (i = 0; i < device->contexts.length; i++)
  1052     {
  1053         WFC_CONTEXT*        ctmp;
  1054 
  1055         ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
  1056         if (ctmp->screenNumber == screenNumber)
  1057         {
  1058             result = ctmp;
  1059             break;
  1060         }
  1061     }
  1062     return result;
  1063 
  1064 }
  1065 
  1066 /*---------------------------------------------------------------------------
  1067  *  Called from context's destructor to clean up any elements that
  1068  *  weren't added to any scene at all i.e. they only reside in the
  1069  *  device's element list. These elements must not stay alive after
  1070  *  the context has been deleted.
  1071  *----------------------------------------------------------------------------*/
  1072 OWF_API_CALL void
  1073 WFC_Device_DestroyContextElements(WFC_DEVICE* device,
  1074                                   WFC_CONTEXT* context)
  1075 {
  1076     WFCint                  i;
  1077 
  1078     DPRINT(("WFC_Device_DestroyContextElements(device=%d, context=%d",
  1079             device ? device->handle : 0,
  1080             context ? context->handle : 0));
  1081 
  1082     if (!device || !context)
  1083     {
  1084         return;
  1085     }
  1086 
  1087     for (i = device->elements.length; i > 0; i--)
  1088     {
  1089         WFC_ELEMENT*        element;
  1090 
  1091         element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i-1));
  1092         if (element->context == context)
  1093         {
  1094             DPRINT(("  Destroying element %d (%p)", element->handle, element));
  1095 
  1096             /* Improvement idea: This code is partially same as in
  1097              * WFC_Device_RemoveElement. Maybe the common part should
  1098              * be isolated into some DoRemoveElement function which then
  1099              * would be called from here and RemoveElement.
  1100              */
  1101             WFC_Context_RemoveElement(CONTEXT(element->context), element->handle);
  1102             OWF_Array_RemoveItemAt(&device->elements, i-1);
  1103             WFC_Element_Destroy(element);
  1104         }
  1105     }
  1106 }
  1107 
  1108 /*---------------------------------------------------------------------------
  1109  *
  1110  *----------------------------------------------------------------------------*/
  1111 OWF_API_CALL void
  1112 WFC_Device_DestroyContextImageProviders(WFC_DEVICE* device,
  1113                                         WFC_CONTEXT* context)
  1114 {
  1115     WFCint                  i;
  1116     
  1117 	DPRINT(("WFC_Device_DestroyContextImageProviders(device=%d, context=%d",
  1118 	device ? device->handle : 0,
  1119 	context ? context->handle : 0));
  1120 
  1121     if (!device || !context)
  1122     {
  1123         return;
  1124     }
  1125 
  1126     for (i = device->providers.length; i > 0; i--)
  1127     {
  1128         WFC_IMAGE_PROVIDER* provider;
  1129 
  1130         provider = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i-1));
  1131         if (provider->owner == context)
  1132         {
  1133             DPRINT(("  Destroying image provider %d (%p)",
  1134                     provider->handle, provider));
  1135 
  1136             WFC_Device_DestroyImageProvider(device, provider->handle);
  1137         }
  1138     }
  1139 }
  1140 
  1141 OWF_API_CALL WFCboolean
  1142 WFC_Device_FindScreenNumber(WFCint screenNumber)
  1143 {
  1144     WFCint i, j, deviceArrayLength, contextArrayLength;
  1145     WFC_DEVICE* pDevice = NULL;
  1146     ENTER(WFC_Device_DestroyContext);
  1147 
  1148     DPRINT(("WFC_Device_CheckScreenNumber(screenNumber = %d)", screenNumber));
  1149 
  1150     deviceArrayLength = gPhyDevice.iDeviceInstanceArray.length;
  1151     for (i = 0; i < deviceArrayLength; ++i)
  1152     {
  1153         pDevice = DEVICE(OWF_Array_GetItemAt(&(gPhyDevice.iDeviceInstanceArray), i));
  1154         OWF_ASSERT(pDevice);
  1155         if (pDevice)
  1156         {
  1157             contextArrayLength = pDevice->contexts.length;
  1158             for (j = 0; j < contextArrayLength; j++)
  1159             {
  1160                 WFC_CONTEXT*    pContext;
  1161                 pContext = CONTEXT(OWF_Array_GetItemAt(&pDevice->contexts, j));
  1162                 OWF_ASSERT(pContext);
  1163                 if (pContext && (pContext->screenNumber == screenNumber))
  1164                 {
  1165                     return WFC_TRUE;
  1166                 }
  1167             }
  1168         }
  1169     }
  1170     return WFC_FALSE;
  1171 }
  1172 
  1173 #ifdef __cplusplus
  1174 }
  1175 #endif