mshtml: Added PluginHost's IPropertyNotifySink stub implementation.
[wine] / dlls / mshtml / pluginhost.c
1 /*
2  * Copyright 2010 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 "config.h"
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29 #include "shlobj.h"
30
31 #include "mshtml_private.h"
32 #include "pluginhost.h"
33
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 static void activate_plugin(PluginHost *host)
40 {
41     IClientSecurity *client_security;
42     IQuickActivate *quick_activate;
43     HRESULT hres;
44
45     if(!host->plugin_unk)
46         return;
47
48     /* Note native calls QI on plugin for an undocumented IID and CLSID_HTMLDocument */
49
50     /* FIXME: call FreezeEvents(TRUE) */
51
52     hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IClientSecurity, (void**)&client_security);
53     if(SUCCEEDED(hres)) {
54         FIXME("Handle IClientSecurity\n");
55         IClientSecurity_Release(client_security);
56         return;
57     }
58
59     hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IQuickActivate, (void**)&quick_activate);
60     if(SUCCEEDED(hres)) {
61         QACONTAINER container = {sizeof(container)};
62         QACONTROL control = {sizeof(control)};
63
64         container.pClientSite = &host->IOleClientSite_iface;
65         container.dwAmbientFlags = QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE;
66         container.pAdviseSink = &host->IAdviseSinkEx_iface;
67         container.pPropertyNotifySink = &host->IPropertyNotifySink_iface;
68
69         hres = IQuickActivate_QuickActivate(quick_activate, &container, &control);
70         if(FAILED(hres))
71             FIXME("QuickActivate failed: %08x\n", hres);
72     }else {
73         FIXME("No IQuickActivate\n");
74     }
75 }
76
77 void update_plugin_window(PluginHost *host, HWND hwnd, const RECT *rect)
78 {
79     if(!hwnd || (host->hwnd && host->hwnd != hwnd)) {
80         FIXME("unhandled hwnd\n");
81         return;
82     }
83
84     if(!host->hwnd) {
85         host->hwnd = hwnd;
86         activate_plugin(host);
87     }
88 }
89
90 static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
91 {
92     return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);
93 }
94
95 static HRESULT WINAPI PHClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
96 {
97     PluginHost *This = impl_from_IOleClientSite(iface);
98
99     if(IsEqualGUID(&IID_IUnknown, riid)) {
100         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
101         *ppv = &This->IOleClientSite_iface;
102     }else if(IsEqualGUID(&IID_IOleClientSite, riid)) {
103         TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppv);
104         *ppv = &This->IOleClientSite_iface;
105     }else if(IsEqualGUID(&IID_IAdviseSink, riid)) {
106         TRACE("(%p)->(IID_IAdviseSink %p)\n", This, ppv);
107         *ppv = &This->IAdviseSinkEx_iface;
108     }else if(IsEqualGUID(&IID_IAdviseSinkEx, riid)) {
109         TRACE("(%p)->(IID_IAdviseSinkEx %p)\n", This, ppv);
110         *ppv = &This->IAdviseSinkEx_iface;
111     }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
112         TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppv);
113         *ppv = &This->IPropertyNotifySink_iface;
114     }else {
115         WARN("Unsupported interface %s\n", debugstr_guid(riid));
116         *ppv = NULL;
117         return E_NOINTERFACE;
118     }
119
120     IOleClientSite_AddRef((IUnknown*)*ppv);
121     return S_OK;
122 }
123
124 static ULONG WINAPI PHClientSite_AddRef(IOleClientSite *iface)
125 {
126     PluginHost *This = impl_from_IOleClientSite(iface);
127     LONG ref = InterlockedIncrement(&This->ref);
128
129     TRACE("(%p) ref=%d\n", This, ref);
130
131     return ref;
132 }
133
134 static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface)
135 {
136     PluginHost *This = impl_from_IOleClientSite(iface);
137     LONG ref = InterlockedDecrement(&This->ref);
138
139     TRACE("(%p) ref=%d\n", This, ref);
140
141     if(!ref) {
142         if(This->plugin_unk)
143             IUnknown_Release(This->plugin_unk);
144         heap_free(This);
145     }
146
147     return ref;
148 }
149
150 static HRESULT WINAPI PHClientSite_SaveObject(IOleClientSite *iface)
151 {
152     PluginHost *This = impl_from_IOleClientSite(iface);
153     FIXME("(%p)\n", This);
154     return E_NOTIMPL;
155 }
156
157 static HRESULT WINAPI PHClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
158                                             DWORD dwWhichMoniker, IMoniker **ppmk)
159 {
160     PluginHost *This = impl_from_IOleClientSite(iface);
161     FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
162     return E_NOTIMPL;
163 }
164
165 static HRESULT WINAPI PHClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
166 {
167     PluginHost *This = impl_from_IOleClientSite(iface);
168     FIXME("(%p)->(%p)\n", This, ppContainer);
169     return E_NOTIMPL;
170 }
171
172 static HRESULT WINAPI PHClientSite_ShowObject(IOleClientSite *iface)
173 {
174     PluginHost *This = impl_from_IOleClientSite(iface);
175     FIXME("(%p)\n", This);
176     return E_NOTIMPL;
177 }
178
179 static HRESULT WINAPI PHClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
180 {
181     PluginHost *This = impl_from_IOleClientSite(iface);
182     FIXME("(%p)->(%x)\n", This, fShow);
183     return E_NOTIMPL;
184 }
185
186 static HRESULT WINAPI PHClientSite_RequestNewObjectLayout(IOleClientSite *iface)
187 {
188     PluginHost *This = impl_from_IOleClientSite(iface);
189     FIXME("(%p)\n", This);
190     return E_NOTIMPL;
191 }
192
193 static const IOleClientSiteVtbl OleClientSiteVtbl = {
194     PHClientSite_QueryInterface,
195     PHClientSite_AddRef,
196     PHClientSite_Release,
197     PHClientSite_SaveObject,
198     PHClientSite_GetMoniker,
199     PHClientSite_GetContainer,
200     PHClientSite_ShowObject,
201     PHClientSite_OnShowWindow,
202     PHClientSite_RequestNewObjectLayout
203 };
204
205 static inline PluginHost *impl_from_IAdviseSinkEx(IAdviseSinkEx *iface)
206 {
207     return CONTAINING_RECORD(iface, PluginHost, IAdviseSinkEx_iface);
208 }
209
210 static HRESULT WINAPI PHAdviseSinkEx_QueryInterface(IAdviseSinkEx *iface, REFIID riid, void **ppv)
211 {
212     PluginHost *This = impl_from_IAdviseSinkEx(iface);
213     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
214 }
215
216 static ULONG WINAPI PHAdviseSinkEx_AddRef(IAdviseSinkEx *iface)
217 {
218     PluginHost *This = impl_from_IAdviseSinkEx(iface);
219     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
220 }
221
222 static ULONG WINAPI PHAdviseSinkEx_Release(IAdviseSinkEx *iface)
223 {
224     PluginHost *This = impl_from_IAdviseSinkEx(iface);
225     return IOleClientSite_Release(&This->IOleClientSite_iface);
226 }
227
228 static void WINAPI PHAdviseSinkEx_OnDataChange(IAdviseSinkEx *iface, FORMATETC *pFormatetc, STGMEDIUM *pStgMedium)
229 {
230     PluginHost *This = impl_from_IAdviseSinkEx(iface);
231     FIXME("(%p)->(%p %p)\n", This, pFormatetc, pStgMedium);
232 }
233
234 static void WINAPI PHAdviseSinkEx_OnViewChange(IAdviseSinkEx *iface, DWORD dwAspect, LONG lindex)
235 {
236     PluginHost *This = impl_from_IAdviseSinkEx(iface);
237     FIXME("(%p)->(%d %d)\n", This, dwAspect, lindex);
238 }
239
240 static void WINAPI PHAdviseSinkEx_OnRename(IAdviseSinkEx *iface, IMoniker *pmk)
241 {
242     PluginHost *This = impl_from_IAdviseSinkEx(iface);
243     FIXME("(%p)->(%p)\n", This, pmk);
244 }
245
246 static void WINAPI PHAdviseSinkEx_OnSave(IAdviseSinkEx *iface)
247 {
248     PluginHost *This = impl_from_IAdviseSinkEx(iface);
249     FIXME("(%p)\n", This);
250 }
251
252 static void WINAPI PHAdviseSinkEx_OnClose(IAdviseSinkEx *iface)
253 {
254     PluginHost *This = impl_from_IAdviseSinkEx(iface);
255     FIXME("(%p)\n", This);
256 }
257
258 static void WINAPI PHAdviseSinkEx_OnViewStatusChange(IAdviseSinkEx *iface, DWORD dwViewStatus)
259 {
260     PluginHost *This = impl_from_IAdviseSinkEx(iface);
261     FIXME("(%p)->(%d)\n", This, dwViewStatus);
262 }
263
264 static const IAdviseSinkExVtbl AdviseSinkExVtbl = {
265     PHAdviseSinkEx_QueryInterface,
266     PHAdviseSinkEx_AddRef,
267     PHAdviseSinkEx_Release,
268     PHAdviseSinkEx_OnDataChange,
269     PHAdviseSinkEx_OnViewChange,
270     PHAdviseSinkEx_OnRename,
271     PHAdviseSinkEx_OnSave,
272     PHAdviseSinkEx_OnClose,
273     PHAdviseSinkEx_OnViewStatusChange
274 };
275
276 static inline PluginHost *impl_from_IPropertyNotifySink(IPropertyNotifySink *iface)
277 {
278     return CONTAINING_RECORD(iface, PluginHost, IPropertyNotifySink_iface);
279 }
280
281 static HRESULT WINAPI PHPropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, REFIID riid, void **ppv)
282 {
283     PluginHost *This = impl_from_IPropertyNotifySink(iface);
284     return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv);
285 }
286
287 static ULONG WINAPI PHPropertyNotifySink_AddRef(IPropertyNotifySink *iface)
288 {
289     PluginHost *This = impl_from_IPropertyNotifySink(iface);
290     return IOleClientSite_AddRef(&This->IOleClientSite_iface);
291 }
292
293 static ULONG WINAPI PHPropertyNotifySink_Release(IPropertyNotifySink *iface)
294 {
295     PluginHost *This = impl_from_IPropertyNotifySink(iface);
296     return IOleClientSite_Release(&This->IOleClientSite_iface);
297 }
298
299 static HRESULT WINAPI PHPropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
300 {
301     PluginHost *This = impl_from_IPropertyNotifySink(iface);
302     FIXME("(%p)->(%d)\n", This, dispID);
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
307 {
308     PluginHost *This = impl_from_IPropertyNotifySink(iface);
309     FIXME("(%p)->(%d)\n", This, dispID);
310     return E_NOTIMPL;
311 }
312
313 static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
314     PHPropertyNotifySink_QueryInterface,
315     PHPropertyNotifySink_AddRef,
316     PHPropertyNotifySink_Release,
317     PHPropertyNotifySink_OnChanged,
318     PHPropertyNotifySink_OnRequestEdit
319 };
320
321 HRESULT create_plugin_host(IUnknown *unk, PluginHost **ret)
322 {
323     PluginHost *host;
324
325     host = heap_alloc_zero(sizeof(*host));
326     if(!host)
327         return E_OUTOFMEMORY;
328
329     host->IOleClientSite_iface.lpVtbl      = &OleClientSiteVtbl;
330     host->IAdviseSinkEx_iface.lpVtbl       = &AdviseSinkExVtbl;
331     host->IPropertyNotifySink_iface.lpVtbl = &PropertyNotifySinkVtbl;
332
333     host->ref = 1;
334
335     IUnknown_AddRef(unk);
336     host->plugin_unk = unk;
337
338     *ret = host;
339     return S_OK;
340 }