When including 'wine/port.h', include it first.
[wine] / dlls / quartz / complist.c
1 /*
2  * List of components. (for internal use)
3  *
4  * hidenori@a2.ctktv.ne.jp
5  */
6
7 #include "config.h"
8
9 #include "windef.h"
10 #include "winbase.h"
11 #include "winerror.h"
12 #include "wine/obj_base.h"
13
14 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(quartz);
16
17 #include "quartz_private.h"
18 #include "complist.h"
19
20
21
22 struct QUARTZ_CompList
23 {
24         QUARTZ_CompListItem*    pFirst;
25         QUARTZ_CompListItem*    pLast;
26         CRITICAL_SECTION                csList;
27 };
28
29 struct QUARTZ_CompListItem
30 {
31         IUnknown*       punk;
32         QUARTZ_CompListItem*    pNext;
33         QUARTZ_CompListItem*    pPrev;
34         void*   pvData;
35         DWORD   dwDataLen;
36 };
37
38
39 QUARTZ_CompList* QUARTZ_CompList_Alloc( void )
40 {
41         QUARTZ_CompList*        pList;
42
43         pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) );
44         if ( pList != NULL )
45         {
46                 /* construct. */
47                 pList->pFirst = NULL;
48                 pList->pLast = NULL;
49
50                 InitializeCriticalSection( &pList->csList );
51         }
52
53         return pList;
54 }
55
56 void QUARTZ_CompList_Free( QUARTZ_CompList* pList )
57 {
58         QUARTZ_CompListItem*    pCur;
59         QUARTZ_CompListItem*    pNext;
60
61         if ( pList != NULL )
62         {
63                 pCur = pList->pFirst;
64                 while ( pCur != NULL )
65                 {
66                         pNext = pCur->pNext;
67                         if ( pCur->punk != NULL )
68                                 IUnknown_Release( pCur->punk );
69                         if ( pCur->pvData != NULL )
70                                 QUARTZ_FreeMem( pCur->pvData );
71                         QUARTZ_FreeMem( pCur );
72                         pCur = pNext;
73                 }
74
75                 DeleteCriticalSection( &pList->csList );
76
77                 QUARTZ_FreeMem( pList );
78         }
79 }
80
81 void QUARTZ_CompList_Lock( QUARTZ_CompList* pList )
82 {
83         EnterCriticalSection( &pList->csList );
84 }
85
86 void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList )
87 {
88         LeaveCriticalSection( &pList->csList );
89 }
90
91 QUARTZ_CompList* QUARTZ_CompList_Dup(
92         const QUARTZ_CompList* pList, BOOL fDupData )
93 {
94         QUARTZ_CompList*        pNewList;
95         const QUARTZ_CompListItem*      pCur;
96         HRESULT hr;
97
98         pNewList = QUARTZ_CompList_Alloc();
99         if ( pNewList == NULL )
100                 return NULL;
101
102         pCur = pList->pFirst;
103         while ( pCur != NULL )
104         {
105                 if ( pCur->punk != NULL )
106                 {
107                         if ( fDupData )
108                                 hr = QUARTZ_CompList_AddComp(
109                                         pNewList, pCur->punk,
110                                         pCur->pvData, pCur->dwDataLen );
111                         else
112                                 hr = QUARTZ_CompList_AddComp(
113                                         pNewList, pCur->punk, NULL, 0 );
114                         if ( FAILED(hr) )
115                         {
116                                 QUARTZ_CompList_Free( pNewList );
117                                 return NULL;
118                         }
119                 }
120                 pCur = pCur->pNext;
121         }
122
123         return pNewList;
124 }
125
126 static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp(
127         QUARTZ_CompList* pList, IUnknown* punk,
128         const void* pvData, DWORD dwDataLen )
129 {
130         QUARTZ_CompListItem*    pItem;
131
132         pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) );
133         if ( pItem == NULL )
134                 return NULL;
135
136         pItem->pvData = NULL;
137         pItem->dwDataLen = 0;
138         if ( pvData != NULL )
139         {
140                 pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen );
141                 if ( pItem->pvData == NULL )
142                 {
143                         QUARTZ_FreeMem( pItem );
144                         return NULL;
145                 }
146                 memcpy( pItem->pvData, pvData, dwDataLen );
147                 pItem->dwDataLen = dwDataLen;
148         }
149
150         pItem->punk = punk; IUnknown_AddRef(punk);
151
152         return pItem;
153 }
154
155 HRESULT QUARTZ_CompList_AddComp(
156         QUARTZ_CompList* pList, IUnknown* punk,
157         const void* pvData, DWORD dwDataLen )
158 {
159         QUARTZ_CompListItem*    pItem;
160
161         pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
162         if ( pItem == NULL )
163                 return E_OUTOFMEMORY;
164
165         if ( pList->pFirst != NULL )
166                 pList->pFirst->pPrev = pItem;
167         else
168                 pList->pLast = pItem;
169         pItem->pNext = pList->pFirst;
170         pList->pFirst = pItem;
171         pItem->pPrev = NULL;
172
173         return S_OK;
174 }
175
176 HRESULT QUARTZ_CompList_AddTailComp(
177         QUARTZ_CompList* pList, IUnknown* punk,
178         const void* pvData, DWORD dwDataLen )
179 {
180         QUARTZ_CompListItem*    pItem;
181
182         pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
183         if ( pItem == NULL )
184                 return E_OUTOFMEMORY;
185
186         if ( pList->pLast != NULL )
187                 pList->pLast->pNext = pItem;
188         else
189                 pList->pFirst = pItem;
190         pItem->pPrev = pList->pLast;
191         pList->pLast = pItem;
192         pItem->pNext = NULL;
193
194         return S_OK;
195 }
196
197 HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk )
198 {
199         QUARTZ_CompListItem*    pCur;
200
201         pCur = QUARTZ_CompList_SearchComp( pList, punk );
202         if ( pCur == NULL )
203                 return S_FALSE; /* already removed. */
204
205         /* remove from list. */
206         if ( pCur->pNext != NULL )
207                 pCur->pNext->pPrev = pCur->pPrev;
208         else
209                 pList->pLast = pCur->pPrev;
210         if ( pCur->pPrev != NULL )
211                 pCur->pPrev->pNext = pCur->pNext;
212         else
213                 pList->pFirst = pCur->pNext;
214
215         /* release this item. */
216         if ( pCur->punk != NULL )
217                 IUnknown_Release( pCur->punk );
218         if ( pCur->pvData != NULL )
219                 QUARTZ_FreeMem( pCur->pvData );
220         QUARTZ_FreeMem( pCur );
221
222         return S_OK;
223 }
224
225 QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
226         QUARTZ_CompList* pList, IUnknown* punk )
227 {
228         QUARTZ_CompListItem*    pCur;
229
230         pCur = pList->pFirst;
231         while ( pCur != NULL )
232         {
233                 if ( pCur->punk == punk )
234                         return pCur;
235                 pCur = pCur->pNext;
236         }
237
238         return NULL;
239 }
240
241 QUARTZ_CompListItem* QUARTZ_CompList_SearchData(
242         QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen )
243 {
244         QUARTZ_CompListItem*    pCur;
245
246         pCur = pList->pFirst;
247         while ( pCur != NULL )
248         {
249                 if ( pCur->dwDataLen == dwDataLen &&
250                      !memcmp( pCur->pvData, pvData, dwDataLen ) )
251                         return pCur;
252                 pCur = pCur->pNext;
253         }
254
255         return NULL;
256 }
257
258 QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
259         QUARTZ_CompList* pList )
260 {
261         return pList->pFirst;
262 }
263
264 QUARTZ_CompListItem* QUARTZ_CompList_GetLast(
265         QUARTZ_CompList* pList )
266 {
267         return pList->pLast;
268 }
269
270 QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
271         QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev )
272 {
273         return pPrev->pNext;
274 }
275
276 QUARTZ_CompListItem* QUARTZ_CompList_GetPrev(
277         QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext )
278 {
279         return pNext->pPrev;
280 }
281
282 IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem )
283 {
284         return pItem->punk;
285 }
286
287 const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem )
288 {
289         return pItem->pvData;
290 }
291
292 DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem )
293 {
294         return pItem->dwDataLen;
295 }