| /* |
| * List of components. (for internal use) |
| * |
| * hidenori@a2.ctktv.ne.jp |
| */ |
| |
| #include "config.h" |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "wine/obj_base.h" |
| |
| #include "debugtools.h" |
| DEFAULT_DEBUG_CHANNEL(quartz); |
| |
| #include "quartz_private.h" |
| #include "complist.h" |
| |
| |
| |
| struct QUARTZ_CompList |
| { |
| QUARTZ_CompListItem* pFirst; |
| QUARTZ_CompListItem* pLast; |
| CRITICAL_SECTION csList; |
| }; |
| |
| struct QUARTZ_CompListItem |
| { |
| IUnknown* punk; |
| QUARTZ_CompListItem* pNext; |
| QUARTZ_CompListItem* pPrev; |
| void* pvData; |
| DWORD dwDataLen; |
| }; |
| |
| |
| QUARTZ_CompList* QUARTZ_CompList_Alloc( void ) |
| { |
| QUARTZ_CompList* pList; |
| |
| pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) ); |
| if ( pList != NULL ) |
| { |
| /* construct. */ |
| pList->pFirst = NULL; |
| pList->pLast = NULL; |
| |
| InitializeCriticalSection( &pList->csList ); |
| } |
| |
| return pList; |
| } |
| |
| void QUARTZ_CompList_Free( QUARTZ_CompList* pList ) |
| { |
| QUARTZ_CompListItem* pCur; |
| QUARTZ_CompListItem* pNext; |
| |
| if ( pList != NULL ) |
| { |
| pCur = pList->pFirst; |
| while ( pCur != NULL ) |
| { |
| pNext = pCur->pNext; |
| if ( pCur->punk != NULL ) |
| IUnknown_Release( pCur->punk ); |
| if ( pCur->pvData != NULL ) |
| QUARTZ_FreeMem( pCur->pvData ); |
| QUARTZ_FreeMem( pCur ); |
| pCur = pNext; |
| } |
| |
| DeleteCriticalSection( &pList->csList ); |
| |
| QUARTZ_FreeMem( pList ); |
| } |
| } |
| |
| void QUARTZ_CompList_Lock( QUARTZ_CompList* pList ) |
| { |
| EnterCriticalSection( &pList->csList ); |
| } |
| |
| void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList ) |
| { |
| LeaveCriticalSection( &pList->csList ); |
| } |
| |
| QUARTZ_CompList* QUARTZ_CompList_Dup( |
| const QUARTZ_CompList* pList, BOOL fDupData ) |
| { |
| QUARTZ_CompList* pNewList; |
| const QUARTZ_CompListItem* pCur; |
| HRESULT hr; |
| |
| pNewList = QUARTZ_CompList_Alloc(); |
| if ( pNewList == NULL ) |
| return NULL; |
| |
| pCur = pList->pFirst; |
| while ( pCur != NULL ) |
| { |
| if ( pCur->punk != NULL ) |
| { |
| if ( fDupData ) |
| hr = QUARTZ_CompList_AddComp( |
| pNewList, pCur->punk, |
| pCur->pvData, pCur->dwDataLen ); |
| else |
| hr = QUARTZ_CompList_AddComp( |
| pNewList, pCur->punk, NULL, 0 ); |
| if ( FAILED(hr) ) |
| { |
| QUARTZ_CompList_Free( pNewList ); |
| return NULL; |
| } |
| } |
| pCur = pCur->pNext; |
| } |
| |
| return pNewList; |
| } |
| |
| static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp( |
| QUARTZ_CompList* pList, IUnknown* punk, |
| const void* pvData, DWORD dwDataLen ) |
| { |
| QUARTZ_CompListItem* pItem; |
| |
| pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) ); |
| if ( pItem == NULL ) |
| return NULL; |
| |
| pItem->pvData = NULL; |
| pItem->dwDataLen = 0; |
| if ( pvData != NULL ) |
| { |
| pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen ); |
| if ( pItem->pvData == NULL ) |
| { |
| QUARTZ_FreeMem( pItem ); |
| return NULL; |
| } |
| memcpy( pItem->pvData, pvData, dwDataLen ); |
| pItem->dwDataLen = dwDataLen; |
| } |
| |
| pItem->punk = punk; IUnknown_AddRef(punk); |
| |
| return pItem; |
| } |
| |
| HRESULT QUARTZ_CompList_AddComp( |
| QUARTZ_CompList* pList, IUnknown* punk, |
| const void* pvData, DWORD dwDataLen ) |
| { |
| QUARTZ_CompListItem* pItem; |
| |
| pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); |
| if ( pItem == NULL ) |
| return E_OUTOFMEMORY; |
| |
| if ( pList->pFirst != NULL ) |
| pList->pFirst->pPrev = pItem; |
| else |
| pList->pLast = pItem; |
| pItem->pNext = pList->pFirst; |
| pList->pFirst = pItem; |
| pItem->pPrev = NULL; |
| |
| return S_OK; |
| } |
| |
| HRESULT QUARTZ_CompList_AddTailComp( |
| QUARTZ_CompList* pList, IUnknown* punk, |
| const void* pvData, DWORD dwDataLen ) |
| { |
| QUARTZ_CompListItem* pItem; |
| |
| pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); |
| if ( pItem == NULL ) |
| return E_OUTOFMEMORY; |
| |
| if ( pList->pLast != NULL ) |
| pList->pLast->pNext = pItem; |
| else |
| pList->pFirst = pItem; |
| pItem->pPrev = pList->pLast; |
| pList->pLast = pItem; |
| pItem->pNext = NULL; |
| |
| return S_OK; |
| } |
| |
| HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ) |
| { |
| QUARTZ_CompListItem* pCur; |
| |
| pCur = QUARTZ_CompList_SearchComp( pList, punk ); |
| if ( pCur == NULL ) |
| return S_FALSE; /* already removed. */ |
| |
| /* remove from list. */ |
| if ( pCur->pNext != NULL ) |
| pCur->pNext->pPrev = pCur->pPrev; |
| else |
| pList->pLast = pCur->pPrev; |
| if ( pCur->pPrev != NULL ) |
| pCur->pPrev->pNext = pCur->pNext; |
| else |
| pList->pFirst = pCur->pNext; |
| |
| /* release this item. */ |
| if ( pCur->punk != NULL ) |
| IUnknown_Release( pCur->punk ); |
| if ( pCur->pvData != NULL ) |
| QUARTZ_FreeMem( pCur->pvData ); |
| QUARTZ_FreeMem( pCur ); |
| |
| return S_OK; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_SearchComp( |
| QUARTZ_CompList* pList, IUnknown* punk ) |
| { |
| QUARTZ_CompListItem* pCur; |
| |
| pCur = pList->pFirst; |
| while ( pCur != NULL ) |
| { |
| if ( pCur->punk == punk ) |
| return pCur; |
| pCur = pCur->pNext; |
| } |
| |
| return NULL; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_SearchData( |
| QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen ) |
| { |
| QUARTZ_CompListItem* pCur; |
| |
| pCur = pList->pFirst; |
| while ( pCur != NULL ) |
| { |
| if ( pCur->dwDataLen == dwDataLen && |
| !memcmp( pCur->pvData, pvData, dwDataLen ) ) |
| return pCur; |
| pCur = pCur->pNext; |
| } |
| |
| return NULL; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( |
| QUARTZ_CompList* pList ) |
| { |
| return pList->pFirst; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_GetLast( |
| QUARTZ_CompList* pList ) |
| { |
| return pList->pLast; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_GetNext( |
| QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev ) |
| { |
| return pPrev->pNext; |
| } |
| |
| QUARTZ_CompListItem* QUARTZ_CompList_GetPrev( |
| QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext ) |
| { |
| return pNext->pPrev; |
| } |
| |
| IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ) |
| { |
| return pItem->punk; |
| } |
| |
| const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem ) |
| { |
| return pItem->pvData; |
| } |
| |
| DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem ) |
| { |
| return pItem->dwDataLen; |
| } |