Add support for WM_WINDOWPOSCHANGED to save new origin of window.
[wine] / dlls / quartz / enumunk.c
1 /*
2  * Implementation of IEnumUnknown (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 #include "wine/obj_misc.h"
28
29 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
31
32 #include "quartz_private.h"
33 #include "enumunk.h"
34 #include "iunk.h"
35
36
37
38 typedef struct IEnumUnknownImpl
39 {
40         ICOM_VFIELD(IEnumUnknown);
41 } IEnumUnknownImpl;
42
43 typedef struct
44 {
45         QUARTZ_IUnkImpl unk;
46         IEnumUnknownImpl        enumunk;
47         struct QUARTZ_IFEntry   IFEntries[1];
48         QUARTZ_CompList*        pCompList;
49         QUARTZ_CompListItem*    pItemCur;
50 } CEnumUnknown;
51
52 #define CEnumUnknown_THIS(iface,member)         CEnumUnknown*   This = ((CEnumUnknown*)(((char*)iface)-offsetof(CEnumUnknown,member)))
53
54
55
56
57 static HRESULT WINAPI
58 IEnumUnknown_fnQueryInterface(IEnumUnknown* iface,REFIID riid,void** ppobj)
59 {
60         CEnumUnknown_THIS(iface,enumunk);
61
62         TRACE("(%p)->()\n",This);
63
64         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
65 }
66
67 static ULONG WINAPI
68 IEnumUnknown_fnAddRef(IEnumUnknown* iface)
69 {
70         CEnumUnknown_THIS(iface,enumunk);
71
72         TRACE("(%p)->()\n",This);
73
74         return IUnknown_AddRef(This->unk.punkControl);
75 }
76
77 static ULONG WINAPI
78 IEnumUnknown_fnRelease(IEnumUnknown* iface)
79 {
80         CEnumUnknown_THIS(iface,enumunk);
81
82         TRACE("(%p)->()\n",This);
83
84         return IUnknown_Release(This->unk.punkControl);
85 }
86
87 static HRESULT WINAPI
88 IEnumUnknown_fnNext(IEnumUnknown* iface,ULONG cReq,IUnknown** ppunk,ULONG* pcFetched)
89 {
90         CEnumUnknown_THIS(iface,enumunk);
91         HRESULT hr;
92         ULONG   cFetched;
93
94         TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppunk,pcFetched);
95
96         if ( pcFetched == NULL && cReq > 1 )
97                 return E_INVALIDARG;
98         if ( ppunk == NULL )
99                 return E_POINTER;
100
101         QUARTZ_CompList_Lock( This->pCompList );
102
103         hr = NOERROR;
104         cFetched = 0;
105         while ( cReq > 0 )
106         {
107                 if ( This->pItemCur == NULL )
108                 {
109                         hr = S_FALSE;
110                         break;
111                 }
112                 ppunk[ cFetched ++ ] = QUARTZ_CompList_GetItemPtr( This->pItemCur );
113                 IUnknown_AddRef( *ppunk );
114
115                 This->pItemCur =
116                         QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
117                 cReq --;
118         }
119
120         QUARTZ_CompList_Unlock( This->pCompList );
121
122         if ( pcFetched != NULL )
123                 *pcFetched = cFetched;
124
125         return hr;
126 }
127
128 static HRESULT WINAPI
129 IEnumUnknown_fnSkip(IEnumUnknown* iface,ULONG cSkip)
130 {
131         CEnumUnknown_THIS(iface,enumunk);
132         HRESULT hr;
133
134         TRACE("(%p)->()\n",This);
135
136         QUARTZ_CompList_Lock( This->pCompList );
137
138         hr = NOERROR;
139         while ( cSkip > 0 )
140         {
141                 if ( This->pItemCur == NULL )
142                 {
143                         hr = S_FALSE;
144                         break;
145                 }
146                 This->pItemCur =
147                         QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
148                 cSkip --;
149         }
150
151         QUARTZ_CompList_Unlock( This->pCompList );
152
153         return hr;
154 }
155
156 static HRESULT WINAPI
157 IEnumUnknown_fnReset(IEnumUnknown* iface)
158 {
159         CEnumUnknown_THIS(iface,enumunk);
160
161         TRACE("(%p)->()\n",This);
162
163         QUARTZ_CompList_Lock( This->pCompList );
164
165         This->pItemCur = QUARTZ_CompList_GetFirst( This->pCompList );
166
167         QUARTZ_CompList_Unlock( This->pCompList );
168
169         return NOERROR;
170 }
171
172 static HRESULT WINAPI
173 IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk)
174 {
175         CEnumUnknown_THIS(iface,enumunk);
176         HRESULT hr;
177
178         TRACE("(%p)->()\n",This);
179
180         if ( ppunk == NULL )
181                 return E_POINTER;
182
183         QUARTZ_CompList_Lock( This->pCompList );
184
185         hr = QUARTZ_CreateEnumUnknown(
186                 This->IFEntries[0].piid,
187                 (void**)ppunk,
188                 This->pCompList );
189         FIXME( "current pointer must be seeked correctly\n" );
190
191         QUARTZ_CompList_Unlock( This->pCompList );
192
193         return hr;
194 }
195
196
197 static ICOM_VTABLE(IEnumUnknown) ienumunk =
198 {
199         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
200         /* IUnknown fields */
201         IEnumUnknown_fnQueryInterface,
202         IEnumUnknown_fnAddRef,
203         IEnumUnknown_fnRelease,
204         /* IEnumUnknown fields */
205         IEnumUnknown_fnNext,
206         IEnumUnknown_fnSkip,
207         IEnumUnknown_fnReset,
208         IEnumUnknown_fnClone,
209 };
210
211 void QUARTZ_DestroyEnumUnknown(IUnknown* punk)
212 {
213         CEnumUnknown_THIS(punk,unk);
214
215         if ( This->pCompList != NULL )
216                 QUARTZ_CompList_Free( This->pCompList );
217 }
218
219 HRESULT QUARTZ_CreateEnumUnknown(
220         REFIID riidEnum, void** ppobj, const QUARTZ_CompList* pCompList )
221 {
222         CEnumUnknown*   penum;
223         QUARTZ_CompList*        pCompListDup;
224
225         TRACE("(%s,%p,%p)\n",debugstr_guid(riidEnum),ppobj,pCompList);
226
227         pCompListDup = QUARTZ_CompList_Dup( pCompList, FALSE );
228         if ( pCompListDup == NULL )
229                 return E_OUTOFMEMORY;
230
231         penum = (CEnumUnknown*)QUARTZ_AllocObj( sizeof(CEnumUnknown) );
232         if ( penum == NULL )
233         {
234                 QUARTZ_CompList_Free( pCompListDup );
235                 return E_OUTOFMEMORY;
236         }
237
238         QUARTZ_IUnkInit( &penum->unk, NULL );
239         ICOM_VTBL(&penum->enumunk) = &ienumunk;
240
241         penum->IFEntries[0].piid = riidEnum;
242         penum->IFEntries[0].ofsVTPtr =
243                 offsetof(CEnumUnknown,enumunk)-offsetof(CEnumUnknown,unk);
244         penum->pCompList = pCompListDup;
245         penum->pItemCur = QUARTZ_CompList_GetFirst( pCompListDup );
246
247         penum->unk.pEntries = penum->IFEntries;
248         penum->unk.dwEntries = 1;
249         penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumUnknown;
250
251         *ppobj = (void*)(&penum->enumunk);
252
253         return S_OK;
254 }
255