Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[wine] / dlls / quartz / complist.c
1 /*
2  * List of components. (for internal use)
3  *
4  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "wine/obj_base.h"
27
28 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
30
31 #include "quartz_private.h"
32 #include "complist.h"
33
34
35
36 struct QUARTZ_CompList
37 {
38         QUARTZ_CompListItem*    pFirst;
39         QUARTZ_CompListItem*    pLast;
40         CRITICAL_SECTION                csList;
41 };
42
43 struct QUARTZ_CompListItem
44 {
45         IUnknown*       punk;
46         QUARTZ_CompListItem*    pNext;
47         QUARTZ_CompListItem*    pPrev;
48         void*   pvData;
49         DWORD   dwDataLen;
50 };
51
52
53 QUARTZ_CompList* QUARTZ_CompList_Alloc( void )
54 {
55         QUARTZ_CompList*        pList;
56
57         pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) );
58         if ( pList != NULL )
59         {
60                 /* construct. */
61                 pList->pFirst = NULL;
62                 pList->pLast = NULL;
63
64                 InitializeCriticalSection( &pList->csList );
65         }
66
67         return pList;
68 }
69
70 void QUARTZ_CompList_Free( QUARTZ_CompList* pList )
71 {
72         QUARTZ_CompListItem*    pCur;
73         QUARTZ_CompListItem*    pNext;
74
75         if ( pList != NULL )
76         {
77                 pCur = pList->pFirst;
78                 while ( pCur != NULL )
79                 {
80                         pNext = pCur->pNext;
81                         if ( pCur->punk != NULL )
82                                 IUnknown_Release( pCur->punk );
83                         if ( pCur->pvData != NULL )
84                                 QUARTZ_FreeMem( pCur->pvData );
85                         QUARTZ_FreeMem( pCur );
86                         pCur = pNext;
87                 }
88
89                 DeleteCriticalSection( &pList->csList );
90
91                 QUARTZ_FreeMem( pList );
92         }
93 }
94
95 void QUARTZ_CompList_Lock( QUARTZ_CompList* pList )
96 {
97         EnterCriticalSection( &pList->csList );
98 }
99
100 void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList )
101 {
102         LeaveCriticalSection( &pList->csList );
103 }
104
105 QUARTZ_CompList* QUARTZ_CompList_Dup(
106         const QUARTZ_CompList* pList, BOOL fDupData )
107 {
108         QUARTZ_CompList*        pNewList;
109         const QUARTZ_CompListItem*      pCur;
110         HRESULT hr;
111
112         pNewList = QUARTZ_CompList_Alloc();
113         if ( pNewList == NULL )
114                 return NULL;
115
116         pCur = pList->pFirst;
117         while ( pCur != NULL )
118         {
119                 if ( pCur->punk != NULL )
120                 {
121                         if ( fDupData )
122                                 hr = QUARTZ_CompList_AddComp(
123                                         pNewList, pCur->punk,
124                                         pCur->pvData, pCur->dwDataLen );
125                         else
126                                 hr = QUARTZ_CompList_AddComp(
127                                         pNewList, pCur->punk, NULL, 0 );
128                         if ( FAILED(hr) )
129                         {
130                                 QUARTZ_CompList_Free( pNewList );
131                                 return NULL;
132                         }
133                 }
134                 pCur = pCur->pNext;
135         }
136
137         return pNewList;
138 }
139
140 static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp(
141         QUARTZ_CompList* pList, IUnknown* punk,
142         const void* pvData, DWORD dwDataLen )
143 {
144         QUARTZ_CompListItem*    pItem;
145
146         pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) );
147         if ( pItem == NULL )
148                 return NULL;
149
150         pItem->pvData = NULL;
151         pItem->dwDataLen = 0;
152         if ( pvData != NULL )
153         {
154                 pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen );
155                 if ( pItem->pvData == NULL )
156                 {
157                         QUARTZ_FreeMem( pItem );
158                         return NULL;
159                 }
160                 memcpy( pItem->pvData, pvData, dwDataLen );
161                 pItem->dwDataLen = dwDataLen;
162         }
163
164         pItem->punk = punk; IUnknown_AddRef(punk);
165
166         return pItem;
167 }
168
169 HRESULT QUARTZ_CompList_AddComp(
170         QUARTZ_CompList* pList, IUnknown* punk,
171         const void* pvData, DWORD dwDataLen )
172 {
173         QUARTZ_CompListItem*    pItem;
174
175         pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
176         if ( pItem == NULL )
177                 return E_OUTOFMEMORY;
178
179         if ( pList->pFirst != NULL )
180                 pList->pFirst->pPrev = pItem;
181         else
182                 pList->pLast = pItem;
183         pItem->pNext = pList->pFirst;
184         pList->pFirst = pItem;
185         pItem->pPrev = NULL;
186
187         return S_OK;
188 }
189
190 HRESULT QUARTZ_CompList_AddTailComp(
191         QUARTZ_CompList* pList, IUnknown* punk,
192         const void* pvData, DWORD dwDataLen )
193 {
194         QUARTZ_CompListItem*    pItem;
195
196         pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
197         if ( pItem == NULL )
198                 return E_OUTOFMEMORY;
199
200         if ( pList->pLast != NULL )
201                 pList->pLast->pNext = pItem;
202         else
203                 pList->pFirst = pItem;
204         pItem->pPrev = pList->pLast;
205         pList->pLast = pItem;
206         pItem->pNext = NULL;
207
208         return S_OK;
209 }
210
211 HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk )
212 {
213         QUARTZ_CompListItem*    pCur;
214
215         pCur = QUARTZ_CompList_SearchComp( pList, punk );
216         if ( pCur == NULL )
217                 return S_FALSE; /* already removed. */
218
219         /* remove from list. */
220         if ( pCur->pNext != NULL )
221                 pCur->pNext->pPrev = pCur->pPrev;
222         else
223                 pList->pLast = pCur->pPrev;
224         if ( pCur->pPrev != NULL )
225                 pCur->pPrev->pNext = pCur->pNext;
226         else
227                 pList->pFirst = pCur->pNext;
228
229         /* release this item. */
230         if ( pCur->punk != NULL )
231                 IUnknown_Release( pCur->punk );
232         if ( pCur->pvData != NULL )
233                 QUARTZ_FreeMem( pCur->pvData );
234         QUARTZ_FreeMem( pCur );
235
236         return S_OK;
237 }
238
239 QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
240         QUARTZ_CompList* pList, IUnknown* punk )
241 {
242         QUARTZ_CompListItem*    pCur;
243
244         pCur = pList->pFirst;
245         while ( pCur != NULL )
246         {
247                 if ( pCur->punk == punk )
248                         return pCur;
249                 pCur = pCur->pNext;
250         }
251
252         return NULL;
253 }
254
255 QUARTZ_CompListItem* QUARTZ_CompList_SearchData(
256         QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen )
257 {
258         QUARTZ_CompListItem*    pCur;
259
260         pCur = pList->pFirst;
261         while ( pCur != NULL )
262         {
263                 if ( pCur->dwDataLen == dwDataLen &&
264                      !memcmp( pCur->pvData, pvData, dwDataLen ) )
265                         return pCur;
266                 pCur = pCur->pNext;
267         }
268
269         return NULL;
270 }
271
272 QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
273         QUARTZ_CompList* pList )
274 {
275         return pList->pFirst;
276 }
277
278 QUARTZ_CompListItem* QUARTZ_CompList_GetLast(
279         QUARTZ_CompList* pList )
280 {
281         return pList->pLast;
282 }
283
284 QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
285         QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev )
286 {
287         return pPrev->pNext;
288 }
289
290 QUARTZ_CompListItem* QUARTZ_CompList_GetPrev(
291         QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext )
292 {
293         return pNext->pPrev;
294 }
295
296 IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem )
297 {
298         return pItem->punk;
299 }
300
301 const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem )
302 {
303         return pItem->pvData;
304 }
305
306 DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem )
307 {
308         return pItem->dwDataLen;
309 }