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