Transplant KhronosRI changeset 22d01ad3515c -
Bug 1394 - KhronosRI - ARMv5 def files missing
Bug 1395 - KhronosRI - RVCT doesn't like 'OpenVGRI' qualified helper function names
Bug 31 - OpenVG implementation is a stub, so no icons or window decorations are displayed
/* Copyright (c) 2009-2010 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*! \ingroup wfc
* \file wfcdevice.c
*
* \brief SI Device handling
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wfcdevice.h"
#include "wfcelement.h"
#include "wfccontext.h"
#include "wfcimageprovider.h"
#include "owfarray.h"
#include "owfmemory.h"
#include "owfmutex.h"
#include "owfscreen.h"
#include "owftypes.h"
#include "owfobject.h"
#include "owfnativestream.h"
#include "owfnotifications.h"
#include "owfdebug.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_ATTRIBUTES 32
#define FAIL_IF(c,e) if (c) { LEAVE(0); return e; }
#define FIRST_DEVICE_HANDLE 1000
PHYSICAL_DEVICE gPhyDevice;
/*-------------------------------------------------------------------------*//*!
* \internal
*
* Initialize devices with default parameters.
*//*-------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Devices_Initialize()
{
static WFCboolean initialised=WFC_FALSE;
if (!initialised)
{
OWF_Array_Initialize(&(gPhyDevice.iDeviceInstanceArray));
gPhyDevice.gDeviceHandleID = 0;
initialised=WFC_TRUE;
}
}
/*---------------------------------------------------------------------------
*
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCint
WFC_Devices_GetIds(WFCint* idList,
WFCint listCapacity,
const WFCint* filterList)
{
/* We assume there is only one physical device and
* all screens are supported by this device */
WFCint screenNumber = OWF_RESERVED_BAD_SCREEN_NUMBER,
n = MAX_ATTRIBUTES,
i = 0;
WFCboolean hasFilter;
hasFilter = (filterList && (*filterList != WFC_NONE)) ?
WFC_TRUE :
WFC_FALSE;
/* handle filter list, if given */
if (hasFilter)
{
/* scan filter list (up to 32 attributes) */
while (n > 0 && WFC_NONE != filterList[0])
{
switch (filterList[0])
{
case WFC_DEVICE_FILTER_SCREEN_NUMBER:
if (screenNumber!=OWF_RESERVED_BAD_SCREEN_NUMBER && screenNumber!=filterList[1])
{
/* invalid repeated filter on screen number */
return 0;
}
screenNumber = filterList[1];
if (!OWF_Screen_Valid(screenNumber))
{
/* invalid screen number */
return 0;
}
break;
case WFC_NONE:
n = 0;
break;
default:
/* EARLY EXIT - invalid attribute */
return 0;
}
/* Move pointer to next key-value pair */
filterList += 2;
n--;
}
}
/* Return number of available devices */
if (NULL == idList && !hasFilter) {
return 1;
}
for (i = 0, n = 0; i < 1 && listCapacity >= 0; i++) {
/* idList might be NULL when querying all devices w/
* screen number in filter list */
if (idList && n < listCapacity)
{
idList[n] = OWF_SUPPORTED_DEVICE_ID;
}
n++;
}
return n;
}
/*---------------------------------------------------------------------------
* Create instance of a device whose ID
* matches deviceId
*
* \param deviceId ID of the device to create. Must be WFC_DEFAULT_DEVICE_ID
* or some other valid device ID (returned by Devices_GetIds)
*
* \return Handle to created device or WFC_INVALID_HANDLE
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCint
WFC_Device_Create(WFCint deviceId)
{
WFC_DEVICE *dev = NULL;
ENTER(WFC_Device_Create);
WFC_Devices_Initialize();
if (deviceId != WFC_DEFAULT_DEVICE_ID && deviceId != OWF_SUPPORTED_DEVICE_ID)
{
return WFC_INVALID_HANDLE;
}
dev = DEVICE(xalloc(1,sizeof(WFC_DEVICE)));
if (dev == NULL)
{
return WFC_INVALID_HANDLE;
}
dev->handle = FIRST_DEVICE_HANDLE + (gPhyDevice.gDeviceHandleID)++;
dev->deviceId = deviceId;
dev->latestUnreadError = WFC_ERROR_NONE;
dev->mutex = NULL;
OWF_Array_Initialize(&dev->contexts);
OWF_Array_Initialize(&dev->providers);
OWF_Array_Initialize(&dev->elements);
if (!OWF_Array_AppendItem(&(gPhyDevice.iDeviceInstanceArray), dev))
{
xfree(dev);
return WFC_INVALID_HANDLE;
}
LEAVE(WFC_Device_Create);
return dev->handle;
}
/*---------------------------------------------------------------------------
* Set error code for device. Obs! In case the previous
* error code hasn't been read from the device, this function
* does nothing; the new error is set only if "current" error
* is none.
*
* \param dev Device object
* \param code Error to set
*
*----------------------------------------------------------------------------*/
OWF_API_CALL void OWF_APIENTRY
WFC_Device_SetError(WFCDevice dev,
WFCErrorCode code)
{
#ifdef DEBUG_LOG
static char* const errmsg[] =
{
"WFC_ERROR_NONE",
"WFC_ERROR_OUT_OF_MEMORY",
"WFC_ERROR_ILLEGAL_ARGUMENT",
"WFC_ERROR_UNSUPPORTED",
"WFC_ERROR_BAD_ATTRIBUTE",
"WFC_ERROR_IN_USE",
"WFC_ERROR_BUSY",
"WFC_ERROR_BAD_DEVICE",
"WFC_ERROR_BAD_HANDLE",
"WFC_ERROR_INCONSISTENCY",
};
#endif
WFC_DEVICE* device = WFC_Device_FindByHandle(dev);
if (WFC_INVALID_HANDLE == device)
{
/* Invalid device handle. Nothing we can do about it so return. */
return;
}
if (!device->mutex)
{
OWF_Mutex_Init(&device->mutex);
}
OWF_Mutex_Lock(&device->mutex);
if (code == WFC_ERROR_IN_USE)
{
code=WFC_ERROR_IN_USE;
}
if (WFC_INVALID_HANDLE != device) {
if (WFC_ERROR_NONE == device->latestUnreadError &&
code != device->latestUnreadError)
{
#ifdef DEBUG_LOG
char* const msg = errmsg[code > WFC_ERROR_NONE ?
code - WFC_ERROR_OUT_OF_MEMORY + 1 : 0];
(void)msg; //always reference to avoid warning
#endif
DPRINT(("setError(dev = %08x, err = %08x)", dev, code));
DPRINT((" error set to = %04x (%s)", (OWFuint16) code, msg));
device->latestUnreadError = code;
}
}
OWF_Mutex_Unlock(&device->mutex);
}
/*---------------------------------------------------------------------------
* Read and reset last error code from device.
*
* \param device Device object
*
* \return WFCErrorCode
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_GetError(WFC_DEVICE* device)
{
WFCErrorCode err;
OWF_ASSERT(device);
err = device->latestUnreadError;
device->latestUnreadError = WFC_ERROR_NONE;
return err;
}
/*---------------------------------------------------------------------------
* Find device object by handle
*
* \param dev Device handle
*
* \return Matching device object or NULL
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_DEVICE*
WFC_Device_FindByHandle(WFCDevice dev)
{
WFCint i = 0, length = 0;
WFC_DEVICE* pDevice = NULL;
if (dev == WFC_INVALID_HANDLE)
{
return NULL;
}
WFC_Devices_Initialize();
length = gPhyDevice.iDeviceInstanceArray.length;
for (i = 0; i < length; ++i)
{
pDevice = DEVICE(OWF_Array_GetItemAt(&(gPhyDevice.iDeviceInstanceArray), i));
if (pDevice->handle == dev)
{
return pDevice;
}
}
return NULL;
}
/*---------------------------------------------------------------------------
* Get device attribute
*
* \param device Device
* \param attrib Attribute name
* \param value Pointer to where the value should be saved
*
* \return WFCErrorCode
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_GetAttribi(WFC_DEVICE* device,
WFCDeviceAttrib attrib,
WFCint* value)
{
WFCErrorCode result = WFC_ERROR_NONE;
OWF_ASSERT(device);
switch (attrib)
{
case WFC_DEVICE_CLASS:
{
*value = WFC_DEVICE_CLASS_FULLY_CAPABLE;
break;
}
case WFC_DEVICE_ID:
{
*value = device->deviceId;
break;
}
default:
{
result = WFC_ERROR_BAD_ATTRIBUTE;
}
}
return result;
}
/*[][][][] CONTEXTS [][][][][][][][][][][][][][][][][][][][][][][][][][][][]*/
/*---------------------------------------------------------------------------
* Create context on device
*
* \param device Device
* \param stream Target stream for context
* \param type Context type
*
* \return New context
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_CONTEXT*
WFC_Device_CreateContext(WFC_DEVICE* device,
OWFNativeStreamType stream,
WFCContextType type,
WFCint screenNum)
{
WFC_CONTEXT* context;
ENTER(WFC_Device_CreateContext);
OWF_ASSERT(device);
context = WFC_Context_Create(device, stream, type, screenNum);
if (context)
{
if (!OWF_Array_AppendItem(&device->contexts, context))
{
DESTROY(context);
}
}
LEAVE(WFC_Device_CreateContext);
return context;
}
/*---------------------------------------------------------------------------
* Destroy context from device
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_DestroyContext(WFC_DEVICE* device,
WFCContext context)
{
WFCint i;
WFCErrorCode result = WFC_ERROR_BAD_HANDLE;
ENTER(WFC_Device_DestroyContext);
OWF_ASSERT(device);
DPRINT(("WFC_Device_DestroyContext(context = %d)", context));
for (i = 0; i < device->contexts.length; i++)
{
WFC_CONTEXT* ctmp;
ctmp = (WFC_CONTEXT*) OWF_Array_GetItemAt(&device->contexts, i);
if (ctmp->handle == context)
{
WFC_CONTEXT* context;
context = CONTEXT(OWF_Array_RemoveItemAt(&device->contexts, i));
DPRINT((" Shutting down context %d", context->handle));
WFC_Context_Shutdown(context);
DESTROY(context);
result = WFC_ERROR_NONE;
break;
}
}
DPRINT((""));
DPRINT(("-------------------------------------------------------"));
DPRINT(("Device statistics after context destruction:"));
DPRINT((" Contexts: %d", device->contexts.length));
DPRINT((" Elements: %d", device->elements.length));
DPRINT((" Image providers: %d", device->providers.length));
DPRINT(("-------------------------------------------------------"));
LEAVE(WFC_Device_DestroyContext);
return result;
}
/*---------------------------------------------------------------------------
* Destroy all device's contexts
*
* \param device Device object
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_DestroyContexts(WFC_DEVICE* device)
{
WFCint i;
ENTER(WFC_Device_DestroyContexts);
for (i = 0; i < device->contexts.length; i++)
{
WFC_CONTEXT* context;
context = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
WFC_Context_Shutdown(context);
DESTROY(context);
}
OWF_Array_Destroy(&device->contexts);
LEAVE(WFC_Device_DestroyContexts);
}
/*---------------------------------------------------------------------------
* Find context context object by handle
*
* \param device Device
* \param context Context handle
*
* \return Corresponding context object or NULL
* if handle is invalid.
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_CONTEXT*
WFC_Device_FindContext(WFC_DEVICE* device,
WFCContext context)
{
WFCint i;
WFC_CONTEXT* result = NULL;
ENTER(WFC_Device_FindContext);
FAIL_IF(NULL == device, NULL);
for (i = 0; i < device->contexts.length; i++)
{
WFC_CONTEXT* ctmp;
ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
if (ctmp->handle == context)
{
result = ctmp;
break;
}
}
LEAVE(WFC_Device_FindContext);
return result;
}
/*[][][][] ELEMENTS [][][][][][][][][][][][][][][][][][][][][][][][][][][][]*/
/*---------------------------------------------------------------------------
* Create new element
*
* \param device
* \param context
*
* \return New element or NULL
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_ELEMENT*
WFC_Device_CreateElement(WFC_DEVICE* device, WFC_CONTEXT* context)
{
WFC_ELEMENT* element=NULL;
ENTER(WFC_Device_CreateElement);
FAIL_IF(NULL == device || NULL == context, NULL);
if (WFC_Context_IncreaseClientElementCount(context)>0)
{
element = WFC_Element_Create(context);
if (!element || !OWF_Array_AppendItem(&device->elements, element))
{
DPRINT(("WFC_Device_CreateElement: couldn't create element"));
WFC_Context_DecreaseClientElementCount(context);
if (element)
{
WFC_Element_Destroy(element);
}
element = NULL;
}
else
{
/* #4585: statement moved to else block */
DPRINT((" Created element; handle = %d", element->handle));
}
}
LEAVE(WFC_Device_CreateElement);
return element;
}
/*---------------------------------------------------------------------------
* Destroy element
*
* \param device
* \param element
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_DestroyElement(WFC_DEVICE* device,
WFCElement element)
{
WFCint i;
WFCErrorCode result = WFC_ERROR_BAD_HANDLE;
ENTER(WFC_Device_DestroyElement);
FAIL_IF(NULL == device, WFC_ERROR_BAD_HANDLE);
DPRINT(("destroying element %d", element));
for (i = 0; i < device->elements.length; i++)
{
WFC_ELEMENT* object;
object = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
DPRINT((" element %d = %d", i, object->handle));
if (object->handle == element)
{
WFC_Context_RemoveElement(CONTEXT(object->context), element);
WFC_Context_DecreaseClientElementCount(object->context);
OWF_Array_RemoveItemAt(&device->elements, i);
WFC_Element_Destroy(object);
result = WFC_ERROR_NONE;
break;
}
}
LEAVE(WFC_Device_DestroyElement);
return result;
}
/*---------------------------------------------------------------------------
* Destroy all elements from device
*
* \param device Device
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_DestroyElements(WFC_DEVICE* device)
{
WFCint i;
ENTER(WFC_Device_DestroyElements);
OWF_ASSERT(device);
for (i = 0; i < device->elements.length; i++)
{
WFC_ELEMENT* etemp;
etemp = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
WFC_Element_Destroy(etemp);
}
OWF_Array_Destroy(&device->elements);
LEAVE(WFC_Device_DestroyElements);
}
/*---------------------------------------------------------------------------
* Find element by handle
*
* \param device Device
* \param el Element handle
*
* \return Element object
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_ELEMENT*
WFC_Device_FindElement(WFC_DEVICE* device,
WFCElement el)
{
WFC_ELEMENT* result = WFC_INVALID_HANDLE;
WFCint i;
FAIL_IF(NULL == device, NULL);
for (i = 0; i < device->elements.length; i++)
{
WFC_ELEMENT* element;
element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i));
if (element->handle == el)
{
result = element;
break;
}
}
return result;
}
/*---------------------------------------------------------------------------
* Set element integer vector attribute
*
* \param device Device
* \param element Element handle
* \param attrib Attribute name
* \param count Attribute value vector length (1 for scalar attribute)
* \param values Pointer to values
*
* \return WFCErrorCode: WFC_ERROR_BAD_ATTRIBUTE if attribute name is invalid;
* WFC_ERROR_INVALID_ARGUMENT if values is NULL or if the count doesn't match
* the attribute's size; WFC_ERROR_BAD_HANDLE if element handle is invalid.
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_SetElementAttribiv(WFC_DEVICE* device,
WFCElement element,
WFCElementAttrib attrib,
WFCint count,
const WFCint* values)
{
WFC_ELEMENT* object;
OWF_ASSERT(device);
object = WFC_Device_FindElement(device, element);
FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
return WFC_Element_SetAttribiv(object, attrib, count, values);
}
/*---------------------------------------------------------------------------
*
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_SetElementAttribfv(WFC_DEVICE* device,
WFCElement element,
WFCElementAttrib attrib,
WFCint count,
const WFCfloat* values)
{
WFC_ELEMENT* object;
OWF_ASSERT(device);
object = WFC_Device_FindElement(device, element);
FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
return WFC_Element_SetAttribfv(object, attrib, count, values);
}
/*---------------------------------------------------------------------------
*
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_GetElementAttribiv(WFC_DEVICE* device,
WFCElement element,
WFCElementAttrib attrib,
WFCint count,
WFCint* values)
{
WFC_ELEMENT* object;
OWF_ASSERT(device);
object = WFC_Device_FindElement(device, element);
FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
return WFC_Element_GetAttribiv(object, attrib, count, values);
}
/*---------------------------------------------------------------------------
*
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_GetElementAttribfv(WFC_DEVICE* device,
WFCElement element,
WFCElementAttrib attrib,
WFCint count,
WFCfloat* values)
{
WFC_ELEMENT* object;
OWF_ASSERT(device);
object = WFC_Device_FindElement(device, element);
FAIL_IF(NULL == object, WFC_ERROR_BAD_HANDLE);
return WFC_Element_GetAttribfv(object, attrib, count, values);
}
/*[][][][] IMAGE PROVIDERS [][][][][][][][][][][][][][][][][][][][][][][][][]*/
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_EnableContentNotifications(WFC_DEVICE* device,
WFC_CONTEXT* context,
WFCboolean enable)
{
WFCint i;
OWF_ASSERT(device);
OWF_ASSERT(context);
context = context;
for (i = 0; i < device->providers.length; i++)
{
WFC_IMAGE_PROVIDER* prov;
prov = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
owfNativeStreamEnableUpdateNotifications(prov->streamHandle,
enable ? OWF_TRUE : OWF_FALSE);
}
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
static WFC_IMAGE_PROVIDER*
WFC_Device_CreateImageProvider(WFC_DEVICE* device,
WFC_CONTEXT* context,
OWFNativeStreamType stream,
WFC_IMAGE_PROVIDER_TYPE type)
{
WFC_IMAGE_PROVIDER* provider;
WFCint success;
OWF_ASSERT(device);
OWF_ASSERT(context);
/* create/fetch stream-wrapper for native stream. */
/* create new image provider object associated to
* native stream wrapper previously fetched */
provider = WFC_ImageProvider_Create(context, stream, type);
if (!provider)
{
return NULL;
}
success = OWF_TRUE;
if (OWF_Array_AppendItem(&device->providers, provider) != OWF_TRUE)
{
success = OWF_FALSE;
}
if (!success || !owfSymDeviceInitialise(provider))
{
OWF_Array_RemoveItem(&device->providers, provider);
success = OWF_FALSE;
}
if (!success)
{
DESTROY(provider);
provider = NULL;
}
return provider;
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
static WFCErrorCode
WFC_Device_DestroyImageProvider(WFC_DEVICE* device,
WFCHandle handle)
{
WFCint i;
WFCErrorCode result = WFC_ERROR_BAD_HANDLE;
ENTER(WFC_Device_DestroyImageProvider);
OWF_ASSERT(device);
DPRINT((" number of providers = %d", device->providers.length));
for (i = 0; i < device->providers.length; i++)
{
WFC_IMAGE_PROVIDER* object;
object = (WFC_IMAGE_PROVIDER*)OWF_Array_GetItemAt(&device->providers, i);
OWF_ASSERT(object);
if (object->handle == handle)
{
DPRINT((" Destroying image provider %d", handle));
owfSymDeviceDestroy(device, object, i);
OWF_Array_RemoveItemAt(&device->providers, i);
DESTROY(object);
result = WFC_ERROR_NONE;
break;
}
}
/*
* Image provider's source content observer should be removed here,
* but on the other hand, it'll be removed when the image provider's
* source stream gets destroyed.
*/
LEAVE(WFC_Device_DestroyImageProvider);
return result;
}
/*---------------------------------------------------------------------------
* Destroy all image providers from device
*
* \param device Device
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_DestroyImageProviders(WFC_DEVICE* device)
{
WFCint i;
ENTER(WFC_Device_DestroyImageProviders);
OWF_ASSERT(device);
DPRINT(("number of providers = %d", device->providers.length));
for (i = 0; i < device->providers.length; i++)
{
WFC_IMAGE_PROVIDER* itemp;
itemp = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
DESTROY(itemp);
}
OWF_Array_Destroy(&device->providers);
LEAVE(WFC_Device_DestroyImageProviders);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_IMAGE_PROVIDER*
WFC_Device_FindImageProvider(WFC_DEVICE* device,
WFCHandle handle,
WFC_IMAGE_PROVIDER_TYPE type)
{
WFCint i;
WFC_IMAGE_PROVIDER* result = WFC_INVALID_HANDLE;
ENTER(WFC_Device_FindImageProvider);
OWF_ASSERT(device);
DPRINT(("number of providers = %d", device->providers.length));
for (i = 0; i < device->providers.length; i++)
{
WFC_IMAGE_PROVIDER* object;
object = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i));
if (object->handle == handle && object->type == type)
{
result = object;
break;
}
}
LEAVE(WFC_Device_FindImageProvider);
return result;
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_IMAGE_PROVIDER*
WFC_Device_CreateSource(WFC_DEVICE* device,
WFC_CONTEXT* context,
WFCNativeStreamType stream)
{
OWF_ASSERT(device);
OWF_ASSERT(context);
return WFC_Device_CreateImageProvider(device,
context, stream, WFC_IMAGE_SOURCE);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_IMAGE_PROVIDER*
WFC_Device_CreateMask(WFC_DEVICE* device,
WFC_CONTEXT* context,
WFCNativeStreamType stream)
{
OWF_ASSERT(device);
OWF_ASSERT(context);
return WFC_Device_CreateImageProvider(device,
context, stream, WFC_IMAGE_MASK);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_DestroySource(WFC_DEVICE* device, WFCSource source)
{
OWF_ASSERT(device);
return WFC_Device_DestroyImageProvider(device, source);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCErrorCode
WFC_Device_DestroyMask(WFC_DEVICE* device, WFCMask mask)
{
OWF_ASSERT(device);
return WFC_Device_DestroyImageProvider(device, mask);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_IMAGE_PROVIDER*
WFC_Device_FindSource(WFC_DEVICE* device, WFCSource source)
{
OWF_ASSERT(device);
return WFC_Device_FindImageProvider(device, source, WFC_IMAGE_SOURCE);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_IMAGE_PROVIDER*
WFC_Device_FindMask(WFC_DEVICE* device, WFCMask mask)
{
OWF_ASSERT(device);
return WFC_Device_FindImageProvider(device, mask, WFC_IMAGE_MASK);
}
/*---------------------------------------------------------------------------
* Destroy device, or rather queue it for destruction.
*
* \param device Device
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_Destroy(WFC_DEVICE* device)
{
ENTER(WFC_Device_Destroy);
OWF_ASSERT(device);
/* release resources */
WFC_Device_DestroyElements(device);
WFC_Device_DestroyImageProviders(device);
WFC_Device_DestroyContexts(device);
OWF_Mutex_Destroy(&device->mutex);
device->mutex = NULL;
device->latestUnreadError = WFC_ERROR_NONE;
device->handle = WFC_INVALID_HANDLE;
OWF_Array_RemoveItem(&(gPhyDevice.iDeviceInstanceArray), device);
xfree(device);
if (gPhyDevice.iDeviceInstanceArray.length == 0)
{
OWF_Array_Destroy(&(gPhyDevice.iDeviceInstanceArray));
}
LEAVE(WFC_Device_Destroy);
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFCboolean
WFC_Device_StreamIsTarget(WFC_DEVICE* device,
WFCNativeStreamType stream)
{
WFCint i;
WFCboolean result = WFC_FALSE;
OWF_ASSERT(device);
for (i = 0; i < device->contexts.length; i++)
{
WFC_CONTEXT* ctmp;
ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
if (ctmp->stream == stream)
{
result = WFC_TRUE;
break;
}
}
return result;
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL WFC_CONTEXT*
WFC_Device_FindContextByScreen(WFC_DEVICE* device,
WFCint screenNumber)
{
WFCint i;
WFC_CONTEXT* result = NULL;
OWF_ASSERT(device);
for (i = 0; i < device->contexts.length; i++)
{
WFC_CONTEXT* ctmp;
ctmp = CONTEXT(OWF_Array_GetItemAt(&device->contexts, i));
if (ctmp->screenNumber == screenNumber)
{
result = ctmp;
break;
}
}
return result;
}
/*---------------------------------------------------------------------------
* Called from context's destructor to clean up any elements that
* weren't added to any scene at all i.e. they only reside in the
* device's element list. These elements must not stay alive after
* the context has been deleted.
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_DestroyContextElements(WFC_DEVICE* device,
WFC_CONTEXT* context)
{
WFCint i;
DPRINT(("WFC_Device_DestroyContextElements(device=%d, context=%d",
device ? device->handle : 0,
context ? context->handle : 0));
if (!device || !context)
{
return;
}
for (i = device->elements.length; i > 0; i--)
{
WFC_ELEMENT* element;
element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i-1));
if (element->context == context)
{
DPRINT((" Destroying element %d (%p)", element->handle, element));
/* Improvement idea: This code is partially same as in
* WFC_Device_RemoveElement. Maybe the common part should
* be isolated into some DoRemoveElement function which then
* would be called from here and RemoveElement.
*/
WFC_Context_RemoveElement(CONTEXT(element->context), element->handle);
OWF_Array_RemoveItemAt(&device->elements, i-1);
WFC_Element_Destroy(element);
}
}
}
/*---------------------------------------------------------------------------
*
*----------------------------------------------------------------------------*/
OWF_API_CALL void
WFC_Device_DestroyContextImageProviders(WFC_DEVICE* device,
WFC_CONTEXT* context)
{
WFCint i;
DPRINT(("WFC_Device_DestroyContextImageProviders(device=%d, context=%d",
device ? device->handle : 0,
context ? context->handle : 0));
if (!device || !context)
{
return;
}
for (i = device->providers.length; i > 0; i--)
{
WFC_IMAGE_PROVIDER* provider;
provider = IMAGE_PROVIDER(OWF_Array_GetItemAt(&device->providers, i-1));
if (provider->owner == context)
{
DPRINT((" Destroying image provider %d (%p)",
provider->handle, provider));
WFC_Device_DestroyImageProvider(device, provider->handle);
}
}
}
#ifdef __cplusplus
}
#endif