push b79aff4f9e064e6702329573e5ebb8548e254b61
[wine/hacks.git] / dlls / mshtml / conpoint.c
blobb5c969c82cdd68a6fd91cd3806bed2438e5d42db
1 /*
2 * Copyright 2006 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
31 #include "wine/debug.h"
33 #include "mshtml_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37 #define CONPOINT(x) ((IConnectionPoint*) &(x)->lpConnectionPointVtbl);
39 void call_property_onchanged(ConnectionPoint *This, DISPID dispid)
41 DWORD i;
43 for(i=0; i<This->sinks_size; i++) {
44 if(This->sinks[i].propnotif)
45 IPropertyNotifySink_OnChanged(This->sinks[i].propnotif, dispid);
49 #define CONPOINT_THIS(iface) DEFINE_THIS(ConnectionPoint, ConnectionPoint, iface)
51 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
52 REFIID riid, LPVOID *ppv)
54 ConnectionPoint *This = CONPOINT_THIS(iface);
56 *ppv = NULL;
58 if(IsEqualGUID(&IID_IUnknown, riid)) {
59 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
60 *ppv = CONPOINT(This);
61 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
62 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv);
63 *ppv = CONPOINT(This);
66 if(*ppv) {
67 IUnknown_AddRef((IUnknown*)*ppv);
68 return S_OK;
71 WARN("Unsupported interface %s\n", debugstr_guid(riid));
72 return E_NOINTERFACE;
75 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
77 ConnectionPoint *This = CONPOINT_THIS(iface);
78 return IConnectionPointContainer_AddRef(This->container);
81 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
83 ConnectionPoint *This = CONPOINT_THIS(iface);
84 return IConnectionPointContainer_Release(This->container);
87 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
89 ConnectionPoint *This = CONPOINT_THIS(iface);
91 TRACE("(%p)->(%p)\n", This, pIID);
93 if(!pIID)
94 return E_POINTER;
96 memcpy(pIID, &This->iid, sizeof(IID));
97 return S_OK;
100 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
101 IConnectionPointContainer **ppCPC)
103 ConnectionPoint *This = CONPOINT_THIS(iface);
105 TRACE("(%p)->(%p)\n", This, ppCPC);
107 if(!ppCPC)
108 return E_POINTER;
110 *ppCPC = This->container;
111 IConnectionPointContainer_AddRef(*ppCPC);
112 return S_OK;
115 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
116 DWORD *pdwCookie)
118 ConnectionPoint *This = CONPOINT_THIS(iface);
119 IUnknown *sink;
120 DWORD i;
121 HRESULT hres;
123 TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie);
125 hres = IUnknown_QueryInterface(pUnkSink, &This->iid, (void**)&sink);
126 if(FAILED(hres) && !IsEqualGUID(&IID_IPropertyNotifySink, &This->iid))
127 hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&sink);
128 if(FAILED(hres))
129 return CONNECT_E_CANNOTCONNECT;
131 if(This->sinks) {
132 for(i=0; i<This->sinks_size; i++) {
133 if(!This->sinks[i].unk)
134 break;
137 if(i == This->sinks_size)
138 This->sinks = mshtml_realloc(This->sinks,(++This->sinks_size)*sizeof(*This->sinks));
139 }else {
140 This->sinks = mshtml_alloc(sizeof(*This->sinks));
141 This->sinks_size = 1;
142 i = 0;
145 This->sinks[i].unk = sink;
146 *pdwCookie = i+1;
148 return S_OK;
151 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
153 ConnectionPoint *This = CONPOINT_THIS(iface);
154 TRACE("(%p)->(%d)\n", This, dwCookie);
156 if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1].unk)
157 return CONNECT_E_NOCONNECTION;
159 IUnknown_Release(This->sinks[dwCookie-1].unk);
160 This->sinks[dwCookie-1].unk = NULL;
162 return S_OK;
165 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
166 IEnumConnections **ppEnum)
168 ConnectionPoint *This = CONPOINT_THIS(iface);
169 FIXME("(%p)->(%p)\n", This, ppEnum);
170 return E_NOTIMPL;
173 #undef CONPOINT_THIS
175 static const IConnectionPointVtbl ConnectionPointVtbl =
177 ConnectionPoint_QueryInterface,
178 ConnectionPoint_AddRef,
179 ConnectionPoint_Release,
180 ConnectionPoint_GetConnectionInterface,
181 ConnectionPoint_GetConnectionPointContainer,
182 ConnectionPoint_Advise,
183 ConnectionPoint_Unadvise,
184 ConnectionPoint_EnumConnections
187 void ConnectionPoint_Init(ConnectionPoint *cp, IConnectionPointContainer *container,
188 REFIID riid, ConnectionPoint *prev)
190 cp->lpConnectionPointVtbl = &ConnectionPointVtbl;
191 cp->container = container;
192 cp->sinks = NULL;
193 cp->sinks_size = 0;
194 cp->iid = *riid;
195 cp->next = NULL;
197 if(prev)
198 prev->next = cp;
201 static void ConnectionPoint_Destroy(ConnectionPoint *This)
203 int i;
205 for(i=0; i<This->sinks_size; i++) {
206 if(This->sinks[i].unk)
207 IUnknown_Release(This->sinks[i].unk);
210 mshtml_free(This->sinks);
213 #define CONPTCONT_THIS(iface) DEFINE_THIS(ConnectionPointContainer, ConnectionPointContainer, iface)
215 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
216 REFIID riid, void **ppv)
218 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
219 return IUnknown_QueryInterface(This->outer, riid, ppv);
222 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
224 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
225 return IUnknown_AddRef(This->outer);
228 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
230 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
231 return IUnknown_Release(This->outer);
234 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
235 IEnumConnectionPoints **ppEnum)
237 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
238 FIXME("(%p)->(%p)\n", This, ppEnum);
239 return E_NOTIMPL;
242 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
243 REFIID riid, IConnectionPoint **ppCP)
245 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
246 ConnectionPoint *iter;
248 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppCP);
250 *ppCP = NULL;
252 for(iter = This->cp_list; iter; iter = iter->next) {
253 if(IsEqualGUID(&iter->iid, riid))
254 *ppCP = CONPOINT(iter);
257 if(*ppCP) {
258 IConnectionPoint_AddRef(*ppCP);
259 return S_OK;
262 FIXME("unsupported riid %s\n", debugstr_guid(riid));
263 return CONNECT_E_NOCONNECTION;
266 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
267 ConnectionPointContainer_QueryInterface,
268 ConnectionPointContainer_AddRef,
269 ConnectionPointContainer_Release,
270 ConnectionPointContainer_EnumConnectionPoints,
271 ConnectionPointContainer_FindConnectionPoint
274 #undef CONPTCONT_THIS
276 void ConnectionPointContainer_Init(ConnectionPointContainer *This, ConnectionPoint *cp_list,
277 IUnknown *outer)
279 This->lpConnectionPointContainerVtbl = &ConnectionPointContainerVtbl;
280 This->cp_list = cp_list;
281 This->outer = outer;
284 void ConnectionPointContainer_Destroy(ConnectionPointContainer *This)
286 ConnectionPoint *iter = This->cp_list;
288 while(iter) {
289 ConnectionPoint_Destroy(iter);
290 iter = iter->next;