wined3d: Fix error handling in fixed_get_input().
[wine/wine64.git] / dlls / mshtml / conpoint.c
blob8a8be4cfb2e5e528f5088e181524704dff60ea5a
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 static const char *debugstr_cp_guid(REFIID riid)
41 #define X(x) \
42 if(IsEqualGUID(riid, &x)) \
43 return #x
45 X(IID_IPropertyNotifySink);
46 X(DIID_HTMLDocumentEvents);
47 X(DIID_HTMLDocumentEvents2);
48 X(DIID_HTMLTableEvents);
49 X(DIID_HTMLTextContainerEvents);
51 #undef X
53 return debugstr_guid(riid);
56 void call_property_onchanged(ConnectionPoint *This, DISPID dispid)
58 DWORD i;
60 for(i=0; i<This->sinks_size; i++) {
61 if(This->sinks[i].propnotif)
62 IPropertyNotifySink_OnChanged(This->sinks[i].propnotif, dispid);
66 #define CONPOINT_THIS(iface) DEFINE_THIS(ConnectionPoint, ConnectionPoint, iface)
68 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
69 REFIID riid, LPVOID *ppv)
71 ConnectionPoint *This = CONPOINT_THIS(iface);
73 *ppv = NULL;
75 if(IsEqualGUID(&IID_IUnknown, riid)) {
76 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
77 *ppv = CONPOINT(This);
78 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
79 TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv);
80 *ppv = CONPOINT(This);
83 if(*ppv) {
84 IUnknown_AddRef((IUnknown*)*ppv);
85 return S_OK;
88 WARN("Unsupported interface %s\n", debugstr_guid(riid));
89 return E_NOINTERFACE;
92 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
94 ConnectionPoint *This = CONPOINT_THIS(iface);
95 return IConnectionPointContainer_AddRef(This->container);
98 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
100 ConnectionPoint *This = CONPOINT_THIS(iface);
101 return IConnectionPointContainer_Release(This->container);
104 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
106 ConnectionPoint *This = CONPOINT_THIS(iface);
108 TRACE("(%p)->(%p)\n", This, pIID);
110 if(!pIID)
111 return E_POINTER;
113 memcpy(pIID, This->iid, sizeof(IID));
114 return S_OK;
117 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
118 IConnectionPointContainer **ppCPC)
120 ConnectionPoint *This = CONPOINT_THIS(iface);
122 TRACE("(%p)->(%p)\n", This, ppCPC);
124 if(!ppCPC)
125 return E_POINTER;
127 *ppCPC = This->container;
128 IConnectionPointContainer_AddRef(*ppCPC);
129 return S_OK;
132 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
133 DWORD *pdwCookie)
135 ConnectionPoint *This = CONPOINT_THIS(iface);
136 IUnknown *sink;
137 DWORD i;
138 HRESULT hres;
140 TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie);
142 hres = IUnknown_QueryInterface(pUnkSink, This->iid, (void**)&sink);
143 if(FAILED(hres) && !IsEqualGUID(&IID_IPropertyNotifySink, This->iid))
144 hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&sink);
145 if(FAILED(hres))
146 return CONNECT_E_CANNOTCONNECT;
148 if(This->sinks) {
149 for(i=0; i<This->sinks_size; i++) {
150 if(!This->sinks[i].unk)
151 break;
154 if(i == This->sinks_size)
155 This->sinks = mshtml_realloc(This->sinks,(++This->sinks_size)*sizeof(*This->sinks));
156 }else {
157 This->sinks = mshtml_alloc(sizeof(*This->sinks));
158 This->sinks_size = 1;
159 i = 0;
162 This->sinks[i].unk = sink;
163 *pdwCookie = i+1;
165 return S_OK;
168 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
170 ConnectionPoint *This = CONPOINT_THIS(iface);
171 TRACE("(%p)->(%d)\n", This, dwCookie);
173 if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1].unk)
174 return CONNECT_E_NOCONNECTION;
176 IUnknown_Release(This->sinks[dwCookie-1].unk);
177 This->sinks[dwCookie-1].unk = NULL;
179 return S_OK;
182 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
183 IEnumConnections **ppEnum)
185 ConnectionPoint *This = CONPOINT_THIS(iface);
186 FIXME("(%p)->(%p)\n", This, ppEnum);
187 return E_NOTIMPL;
190 #undef CONPOINT_THIS
192 static const IConnectionPointVtbl ConnectionPointVtbl =
194 ConnectionPoint_QueryInterface,
195 ConnectionPoint_AddRef,
196 ConnectionPoint_Release,
197 ConnectionPoint_GetConnectionInterface,
198 ConnectionPoint_GetConnectionPointContainer,
199 ConnectionPoint_Advise,
200 ConnectionPoint_Unadvise,
201 ConnectionPoint_EnumConnections
204 void ConnectionPoint_Init(ConnectionPoint *cp, ConnectionPointContainer *container, REFIID riid)
206 cp->lpConnectionPointVtbl = &ConnectionPointVtbl;
207 cp->container = CONPTCONT(container);
208 cp->sinks = NULL;
209 cp->sinks_size = 0;
210 cp->iid = riid;
211 cp->next = NULL;
213 cp->next = container->cp_list;
214 container->cp_list = cp;
217 static void ConnectionPoint_Destroy(ConnectionPoint *This)
219 int i;
221 for(i=0; i<This->sinks_size; i++) {
222 if(This->sinks[i].unk)
223 IUnknown_Release(This->sinks[i].unk);
226 mshtml_free(This->sinks);
229 #define CONPTCONT_THIS(iface) DEFINE_THIS(ConnectionPointContainer, ConnectionPointContainer, iface)
231 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
232 REFIID riid, void **ppv)
234 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
235 return IUnknown_QueryInterface(This->outer, riid, ppv);
238 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
240 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
241 return IUnknown_AddRef(This->outer);
244 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
246 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
247 return IUnknown_Release(This->outer);
250 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
251 IEnumConnectionPoints **ppEnum)
253 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
254 FIXME("(%p)->(%p)\n", This, ppEnum);
255 return E_NOTIMPL;
258 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
259 REFIID riid, IConnectionPoint **ppCP)
261 ConnectionPointContainer *This = CONPTCONT_THIS(iface);
262 ConnectionPoint *iter;
264 TRACE("(%p)->(%s %p)\n", This, debugstr_cp_guid(riid), ppCP);
266 *ppCP = NULL;
268 for(iter = This->cp_list; iter; iter = iter->next) {
269 if(IsEqualGUID(iter->iid, riid))
270 *ppCP = CONPOINT(iter);
273 if(*ppCP) {
274 IConnectionPoint_AddRef(*ppCP);
275 return S_OK;
278 FIXME("unsupported riid %s\n", debugstr_cp_guid(riid));
279 return CONNECT_E_NOCONNECTION;
282 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
283 ConnectionPointContainer_QueryInterface,
284 ConnectionPointContainer_AddRef,
285 ConnectionPointContainer_Release,
286 ConnectionPointContainer_EnumConnectionPoints,
287 ConnectionPointContainer_FindConnectionPoint
290 #undef CONPTCONT_THIS
292 void ConnectionPointContainer_Init(ConnectionPointContainer *This, IUnknown *outer)
294 This->lpConnectionPointContainerVtbl = &ConnectionPointContainerVtbl;
295 This->cp_list = NULL;
296 This->outer = outer;
299 void ConnectionPointContainer_Destroy(ConnectionPointContainer *This)
301 ConnectionPoint *iter = This->cp_list;
303 while(iter) {
304 ConnectionPoint_Destroy(iter);
305 iter = iter->next;