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