shdocvw: Added InternetExplorer object tests.
[wine] / dlls / mshtml / service.c
1 /*
2  * Copyright 2005 Jacek Caban
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 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30
31 #include "wine/debug.h"
32
33 #include "mshtml_private.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 typedef struct {
38     IOleUndoManager IOleUndoManager_iface;
39
40     LONG ref;
41 } UndoManager;
42
43 static inline UndoManager *impl_from_IOleUndoManager(IOleUndoManager *iface)
44 {
45     return CONTAINING_RECORD(iface, UndoManager, IOleUndoManager_iface);
46 }
47
48 static HRESULT WINAPI OleUndoManager_QueryInterface(IOleUndoManager *iface, REFIID riid, void **ppv)
49 {
50     UndoManager *This = impl_from_IOleUndoManager(iface);
51
52     if(IsEqualGUID(riid, &IID_IUnknown)) {
53         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
54         *ppv = &This->IOleUndoManager_iface;
55     }else if(IsEqualGUID(riid, &IID_IOleUndoManager)) {
56         TRACE("(%p)->(IID_IOleUndoManager %p)\n", This, ppv);
57         *ppv = &This->IOleUndoManager_iface;
58     }else {
59         *ppv = NULL;
60         FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
61         return E_NOINTERFACE;
62     }
63
64     IUnknown_AddRef((IUnknown*)*ppv);
65     return S_OK;
66 }
67
68 static ULONG WINAPI OleUndoManager_AddRef(IOleUndoManager *iface)
69 {
70     UndoManager *This = impl_from_IOleUndoManager(iface);
71     LONG ref = InterlockedIncrement(&This->ref);
72
73     TRACE("(%p) ref=%d\n", This, ref);
74
75     return ref;
76 }
77
78 static ULONG WINAPI OleUndoManager_Release(IOleUndoManager *iface)
79 {
80     UndoManager *This = impl_from_IOleUndoManager(iface);
81     LONG ref = InterlockedDecrement(&This->ref);
82
83     TRACE("(%p) ref=%d\n", This, ref);
84
85     if(!ref)
86         heap_free(This);
87
88     return ref;
89 }
90
91 static HRESULT WINAPI OleUndoManager_Open(IOleUndoManager *iface, IOleParentUndoUnit *pPUU)
92 {
93     UndoManager *This = impl_from_IOleUndoManager(iface);
94     FIXME("(%p)->(%p)\n", This, pPUU);
95     return E_NOTIMPL;
96 }
97
98 static HRESULT WINAPI OleUndoManager_Close(IOleUndoManager *iface, IOleParentUndoUnit *pPUU,
99         BOOL fCommit)
100 {
101     UndoManager *This = impl_from_IOleUndoManager(iface);
102     FIXME("(%p)->(%p %x)\n", This, pPUU, fCommit);
103     return E_NOTIMPL;
104 }
105
106 static HRESULT WINAPI OleUndoManager_Add(IOleUndoManager *iface, IOleUndoUnit *pUU)
107 {
108     UndoManager *This = impl_from_IOleUndoManager(iface);
109     FIXME("(%p)->(%p)\n", This, pUU);
110     return E_NOTIMPL;
111 }
112
113 static HRESULT WINAPI OleUndoManager_GetOpenParentState(IOleUndoManager *iface, DWORD *pdwState)
114 {
115     UndoManager *This = impl_from_IOleUndoManager(iface);
116     FIXME("(%p)->(%p)\n", This, pdwState);
117     return E_NOTIMPL;
118 }
119
120 static HRESULT WINAPI OleUndoManager_DiscardFrom(IOleUndoManager *iface, IOleUndoUnit *pUU)
121 {
122     UndoManager *This = impl_from_IOleUndoManager(iface);
123     FIXME("(%p)->(%p)\n", This, pUU);
124     return S_OK;
125 }
126
127 static HRESULT WINAPI OleUndoManager_UndoTo(IOleUndoManager *iface, IOleUndoUnit *pUU)
128 {
129     UndoManager *This = impl_from_IOleUndoManager(iface);
130     FIXME("(%p)->(%p)\n", This, pUU);
131     return E_NOTIMPL;
132 }
133
134 static HRESULT WINAPI OleUndoManager_RedoTo(IOleUndoManager *iface, IOleUndoUnit *pUU)
135 {
136     UndoManager *This = impl_from_IOleUndoManager(iface);
137     FIXME("(%p)->(%p)\n", This, pUU);
138     return E_NOTIMPL;
139 }
140
141 static HRESULT WINAPI OleUndoManager_EnumUndoable(IOleUndoManager *iface,
142         IEnumOleUndoUnits **ppEnum)
143 {
144     UndoManager *This = impl_from_IOleUndoManager(iface);
145     FIXME("(%p)->(%p)\n", This, ppEnum);
146     return E_NOTIMPL;
147 }
148
149 static HRESULT WINAPI OleUndoManager_EnumRedoable(IOleUndoManager *iface,
150         IEnumOleUndoUnits **ppEnum)
151 {
152     UndoManager *This = impl_from_IOleUndoManager(iface);
153     FIXME("(%p)->(%p)\n", This, ppEnum);
154     return E_NOTIMPL;
155 }
156
157 static HRESULT WINAPI OleUndoManager_GetLastUndoDescription(IOleUndoManager *iface, BSTR *pBstr)
158 {
159     UndoManager *This = impl_from_IOleUndoManager(iface);
160     FIXME("(%p)->(%p)\n", This, pBstr);
161     return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI OleUndoManager_GetLastRedoDescription(IOleUndoManager *iface, BSTR *pBstr)
165 {
166     UndoManager *This = impl_from_IOleUndoManager(iface);
167     FIXME("(%p)->(%p)\n", This, pBstr);
168     return E_NOTIMPL;
169 }
170
171 static HRESULT WINAPI OleUndoManager_Enable(IOleUndoManager *iface, BOOL fEnable)
172 {
173     UndoManager *This = impl_from_IOleUndoManager(iface);
174     FIXME("(%p)->(%x)\n", This, fEnable);
175     return E_NOTIMPL;
176 }
177
178 static const IOleUndoManagerVtbl OleUndoManagerVtbl = {
179     OleUndoManager_QueryInterface,
180     OleUndoManager_AddRef,
181     OleUndoManager_Release,
182     OleUndoManager_Open,
183     OleUndoManager_Close,
184     OleUndoManager_Add,
185     OleUndoManager_GetOpenParentState,
186     OleUndoManager_DiscardFrom,
187     OleUndoManager_UndoTo,
188     OleUndoManager_RedoTo,
189     OleUndoManager_EnumUndoable,
190     OleUndoManager_EnumRedoable,
191     OleUndoManager_GetLastUndoDescription,
192     OleUndoManager_GetLastRedoDescription,
193     OleUndoManager_Enable
194 };
195
196 static IOleUndoManager *create_undomgr(void)
197 {
198     UndoManager *ret = heap_alloc(sizeof(UndoManager));
199
200     ret->IOleUndoManager_iface.lpVtbl = &OleUndoManagerVtbl;
201     ret->ref = 1;
202
203     return &ret->IOleUndoManager_iface;
204 }
205
206 /**********************************************************
207  * IServiceProvider implementation
208  */
209
210 static inline HTMLDocument *impl_from_IServiceProvider(IServiceProvider *iface)
211 {
212     return CONTAINING_RECORD(iface, HTMLDocument, IServiceProvider_iface);
213 }
214
215 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
216 {
217     HTMLDocument *This = impl_from_IServiceProvider(iface);
218     return htmldoc_query_interface(This, riid, ppv);
219 }
220
221 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
222 {
223     HTMLDocument *This = impl_from_IServiceProvider(iface);
224     return htmldoc_addref(This);
225 }
226
227 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
228 {
229     HTMLDocument *This = impl_from_IServiceProvider(iface);
230     return htmldoc_release(This);
231 }
232
233 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
234         REFIID riid, void **ppv)
235 {
236     HTMLDocument *This = impl_from_IServiceProvider(iface);
237
238     if(IsEqualGUID(&CLSID_CMarkup, guidService)) {
239         FIXME("(%p)->(CLSID_CMarkup %s %p)\n", This, debugstr_guid(riid), ppv);
240         return E_NOINTERFACE;
241     }
242
243     if(IsEqualGUID(&SID_SOleUndoManager, guidService)) {
244         TRACE("SID_SOleUndoManager\n");
245
246         if(!This->doc_obj->undomgr)
247             This->doc_obj->undomgr = create_undomgr();
248
249         return IOleUndoManager_QueryInterface(This->doc_obj->undomgr, riid, ppv);
250     }
251
252     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
253
254     if(This->doc_obj->client) {
255         IServiceProvider *sp;
256         HRESULT hres;
257
258         hres = IOleClientSite_QueryInterface(This->doc_obj->client,
259                 &IID_IServiceProvider, (void**)&sp);
260         if(SUCCEEDED(hres)) {
261             hres = IServiceProvider_QueryService(sp, guidService, riid, ppv);
262             IServiceProvider_Release(sp);
263
264             if(SUCCEEDED(hres))
265                 return hres;
266         }
267     }
268
269     FIXME("unknown service %s\n", debugstr_guid(guidService));
270     return E_NOINTERFACE;
271 }
272
273 static const IServiceProviderVtbl ServiceProviderVtbl = {
274     ServiceProvider_QueryInterface,
275     ServiceProvider_AddRef,
276     ServiceProvider_Release,
277     ServiceProvider_QueryService
278 };
279
280 void HTMLDocument_Service_Init(HTMLDocument *This)
281 {
282     This->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
283 }