Fix def files so that the implementation agnostic interface definition has no non-standards defined entry points, and change the eglrefimpl specific implementation to place its private entry points high up in the ordinal order space in the implementation region, not the standards based entrypoints region.
/* Copyright (c) 2009 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);
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