1 /*
2 * Copyright 2006 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29
30 #include "mshtml_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 #define CONPOINT(x) ((IConnectionPoint*) &(x)->lpConnectionPointVtbl);
35
36 static const char *debugstr_cp_guid(REFIID riid)
37 {
38 #define X(x) \
39 if(IsEqualGUID(riid, &x)) \
40 return #x
41
42 X(IID_IPropertyNotifySink);
43 X(DIID_HTMLDocumentEvents);
44 X(DIID_HTMLDocumentEvents2);
45 X(DIID_HTMLTableEvents);
46 X(DIID_HTMLTextContainerEvents);
47
48 #undef X
49
50 return debugstr_guid(riid);
51 }
52
53 void call_property_onchanged(ConnectionPoint *This, DISPID dispid)
54 {
55 DWORD i;
56
57 for(i=0; i<This->sinks_size; i++) {
58 if(This->sinks[i].propnotif)
59 IPropertyNotifySink_OnChanged(This->sinks[i].propnotif, dispid);
60 }
61 }
62
63 #define CONPOINT_THIS(iface) DEFINE_THIS(ConnectionPoint, ConnectionPoint, iface)
64
65 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
66 REFIID riid, LPVOID *ppv)
67 {
68 ConnectionPoint *This = CONPOINT_THIS(iface);
69
70 *ppv = NULL;
71
72 if(IsEqualGUID(&IID_IUnknown, riid)) {
73 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
74 *ppv = CONPOINT(This);
75 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
76 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv);
77 *ppv = CONPOINT(This);
78 }
79
80 if(*ppv) {
81 IUnknown_AddRef((IUnknown*)*ppv);
82 return S_OK;
83 }
84
85 WARN("Unsupported interface %s\n", debugstr_guid(riid));
86 return E_NOINTERFACE;
87 }
88
89 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
90 {
91 ConnectionPoint *This = CONPOINT_THIS(iface);
92 return IConnectionPointContainer_AddRef(This->container);
93 }
94
95 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
96 {
97 ConnectionPoint *This = CONPOINT_THIS(iface);
98 return IConnectionPointContainer_Release(This->container);
99 }
100
101 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
102 {
103 ConnectionPoint *This = CONPOINT_THIS(iface);
104
105 TRACE("(%p)->(%p)\n", This, pIID);
106
107 if(!pIID)
108 return E_POINTER;
109
110 *pIID = *This->iid;
111 return S_OK;
112 }
113
114 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
115 IConnectionPointContainer **ppCPC)
116 {
117 ConnectionPoint *This = CONPOINT_THIS(iface);
118
119 TRACE("(%p)->(%p)\n", This, ppCPC);
120
121 if(!ppCPC)
122 return E_POINTER;
123
124 *ppCPC = This->container;
125 IConnectionPointContainer_AddRef(*ppCPC);
126 return S_OK;
127 }
128
129 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
130 DWORD *pdwCookie)
131 {
132 ConnectionPoint *This = CONPOINT_THIS(iface);
133 IUnknown *sink;
134 DWORD i;
135 HRESULT hres;
136
137 TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie);
138
139 hres = IUnknown_QueryInterface(pUnkSink, This->iid, (void**)&sink);
140 if(FAILED(hres) && !IsEqualGUID(&IID_IPropertyNotifySink, This->iid))
141 hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&sink);
142 if(FAILED(hres))
143 return CONNECT_E_CANNOTCONNECT;
144
145 if(This->sinks) {
146 for(i=0; i<This->sinks_size; i++) {
147 if(!This->sinks[i].unk)
148 break;
149 }
150
151 if(i == This->sinks_size)
152 This->sinks = heap_realloc(This->sinks,(++This->sinks_size)*sizeof(*This->sinks));
153 }else {
154 This->sinks = heap_alloc(sizeof(*This->sinks));
155 This->sinks_size = 1;
156 i = 0;
157 }
158
159 This->sinks[i].unk = sink;
160 *pdwCookie = i+1;
161
162 return S_OK;
163 }
164
165 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
166 {
167 ConnectionPoint *This = CONPOINT_THIS(iface);
168 TRACE("(%p)->(%d)\n", This, dwCookie);
169
170 if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1].unk)
171 return CONNECT_E_NOCONNECTION;
172
173 IUnknown_Release(This->sinks[dwCookie-1].unk);
174 This->sinks[dwCookie-1].unk = NULL;
175
176 return S_OK;
177 }
178
179 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
180 IEnumConnections **ppEnum)
181 {
182 ConnectionPoint *This = CONPOINT_THIS(iface);
183 FIXME("(%p)->(%p)\n", This, ppEnum);
184 return E_NOTIMPL;
185 }
186
187 #undef CONPOINT_THIS
188
189 static const IConnectionPointVtbl ConnectionPointVtbl =
190 {
191 ConnectionPoint_QueryInterface,
192 ConnectionPoint_AddRef,
193 ConnectionPoint_Release,
194 ConnectionPoint_GetConnectionInterface,
195 ConnectionPoint_GetConnectionPointContainer,
196 ConnectionPoint_Advise,
197 ConnectionPoint_Unadvise,
198 ConnectionPoint_EnumConnections
199 };
200
201 void ConnectionPoint_Init(ConnectionPoint *cp, ConnectionPointContainer *container, REFIID riid, cp_static_data_t *data)
202 {
203 cp->lpConnectionPointVtbl = &ConnectionPointVtbl;
204 cp->container = CONPTCONT(container);
205 cp->sinks = NULL;
206 cp->sinks_size = 0;
207 cp->iid = riid;
208 cp->next = NULL;
209 cp->data = data;
210
211 cp->next = container->cp_list;
212 container->cp_list = cp;
213 }
214
215 static void ConnectionPoint_Destroy(ConnectionPoint *This)
216 {
217 DWORD i;
218
219 for(i=0; i<This->sinks_size; i++) {
220 if(This->sinks[i].unk)
221 IUnknown_Release(This->sinks[i].unk);
222 }
223
224 heap_free(This->sinks);
225 }
226
227 #define CONPTCONT_THIS(iface) DEFINE_THIS(ConnectionPointContainer, ConnectionPointContainer, iface)
228
229 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
230 REFIID riid, void **ppv)
231 {
232 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
233 return IUnknown_QueryInterface(This->outer, riid, ppv);
234 }
235
236 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
237 {
238 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
239 return IUnknown_AddRef(This->outer);
240 }
241
242 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
243 {
244 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
245 return IUnknown_Release(This->outer);
246 }
247
248 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
249 IEnumConnectionPoints **ppEnum)
250 {
251 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
252 FIXME("(%p)->(%p)\n", This, ppEnum);
253 return E_NOTIMPL;
254 }
255
256 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
257 REFIID riid, IConnectionPoint **ppCP)
258 {
259 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
260 ConnectionPoint *iter;
261
262 TRACE("(%p)->(%s %p)\n", This, debugstr_cp_guid(riid), ppCP);
263
264 if(This->forward_container)
265 return IConnectionPointContainer_FindConnectionPoint(CONPTCONT(This), riid, ppCP);
266
267 *ppCP = NULL;
268
269 for(iter = This->cp_list; iter; iter = iter->next) {
270 if(IsEqualGUID(iter->iid, riid))
271 *ppCP = CONPOINT(iter);
272 }
273
274 if(*ppCP) {
275 IConnectionPoint_AddRef(*ppCP);
276 return S_OK;
277 }
278
279 FIXME("unsupported riid %s\n", debugstr_cp_guid(riid));
280 return CONNECT_E_NOCONNECTION;
281 }
282
283 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
284 ConnectionPointContainer_QueryInterface,
285 ConnectionPointContainer_AddRef,
286 ConnectionPointContainer_Release,
287 ConnectionPointContainer_EnumConnectionPoints,
288 ConnectionPointContainer_FindConnectionPoint
289 };
290
291 #undef CONPTCONT_THIS
292
293 void ConnectionPointContainer_Init(ConnectionPointContainer *This, IUnknown *outer)
294 {
295 This->lpConnectionPointContainerVtbl = &ConnectionPointContainerVtbl;
296 This->cp_list = NULL;
297 This->outer = outer;
298 }
299
300 void ConnectionPointContainer_Destroy(ConnectionPointContainer *This)
301 {
302 ConnectionPoint *iter = This->cp_list;
303
304 while(iter) {
305 ConnectionPoint_Destroy(iter);
306 iter = iter->next;
307 }
308 }
309
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.