xref: /reactos/dll/win32/mshtml/service.c (revision 40462c92)
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 "mshtml_private.h"
20 
21 typedef struct {
22     IOleUndoManager IOleUndoManager_iface;
23 
24     LONG ref;
25 } UndoManager;
26 
27 static inline UndoManager *impl_from_IOleUndoManager(IOleUndoManager *iface)
28 {
29     return CONTAINING_RECORD(iface, UndoManager, IOleUndoManager_iface);
30 }
31 
32 static HRESULT WINAPI OleUndoManager_QueryInterface(IOleUndoManager *iface, REFIID riid, void **ppv)
33 {
34     UndoManager *This = impl_from_IOleUndoManager(iface);
35 
36     if(IsEqualGUID(riid, &IID_IUnknown)) {
37         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
38         *ppv = &This->IOleUndoManager_iface;
39     }else if(IsEqualGUID(riid, &IID_IOleUndoManager)) {
40         TRACE("(%p)->(IID_IOleUndoManager %p)\n", This, ppv);
41         *ppv = &This->IOleUndoManager_iface;
42     }else {
43         *ppv = NULL;
44         FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
45         return E_NOINTERFACE;
46     }
47 
48     IUnknown_AddRef((IUnknown*)*ppv);
49     return S_OK;
50 }
51 
52 static ULONG WINAPI OleUndoManager_AddRef(IOleUndoManager *iface)
53 {
54     UndoManager *This = impl_from_IOleUndoManager(iface);
55     LONG ref = InterlockedIncrement(&This->ref);
56 
57     TRACE("(%p) ref=%d\n", This, ref);
58 
59     return ref;
60 }
61 
62 static ULONG WINAPI OleUndoManager_Release(IOleUndoManager *iface)
63 {
64     UndoManager *This = impl_from_IOleUndoManager(iface);
65     LONG ref = InterlockedDecrement(&This->ref);
66 
67     TRACE("(%p) ref=%d\n", This, ref);
68 
69     if(!ref)
70         heap_free(This);
71 
72     return ref;
73 }
74 
75 static HRESULT WINAPI OleUndoManager_Open(IOleUndoManager *iface, IOleParentUndoUnit *pPUU)
76 {
77     UndoManager *This = impl_from_IOleUndoManager(iface);
78     FIXME("(%p)->(%p)\n", This, pPUU);
79     return E_NOTIMPL;
80 }
81 
82 static HRESULT WINAPI OleUndoManager_Close(IOleUndoManager *iface, IOleParentUndoUnit *pPUU,
83         BOOL fCommit)
84 {
85     UndoManager *This = impl_from_IOleUndoManager(iface);
86     FIXME("(%p)->(%p %x)\n", This, pPUU, fCommit);
87     return E_NOTIMPL;
88 }
89 
90 static HRESULT WINAPI OleUndoManager_Add(IOleUndoManager *iface, IOleUndoUnit *pUU)
91 {
92     UndoManager *This = impl_from_IOleUndoManager(iface);
93     FIXME("(%p)->(%p)\n", This, pUU);
94     return E_NOTIMPL;
95 }
96 
97 static HRESULT WINAPI OleUndoManager_GetOpenParentState(IOleUndoManager *iface, DWORD *pdwState)
98 {
99     UndoManager *This = impl_from_IOleUndoManager(iface);
100     FIXME("(%p)->(%p)\n", This, pdwState);
101     return E_NOTIMPL;
102 }
103 
104 static HRESULT WINAPI OleUndoManager_DiscardFrom(IOleUndoManager *iface, IOleUndoUnit *pUU)
105 {
106     UndoManager *This = impl_from_IOleUndoManager(iface);
107     FIXME("(%p)->(%p)\n", This, pUU);
108     return S_OK;
109 }
110 
111 static HRESULT WINAPI OleUndoManager_UndoTo(IOleUndoManager *iface, IOleUndoUnit *pUU)
112 {
113     UndoManager *This = impl_from_IOleUndoManager(iface);
114     FIXME("(%p)->(%p)\n", This, pUU);
115     return E_NOTIMPL;
116 }
117 
118 static HRESULT WINAPI OleUndoManager_RedoTo(IOleUndoManager *iface, IOleUndoUnit *pUU)
119 {
120     UndoManager *This = impl_from_IOleUndoManager(iface);
121     FIXME("(%p)->(%p)\n", This, pUU);
122     return E_NOTIMPL;
123 }
124 
125 static HRESULT WINAPI OleUndoManager_EnumUndoable(IOleUndoManager *iface,
126         IEnumOleUndoUnits **ppEnum)
127 {
128     UndoManager *This = impl_from_IOleUndoManager(iface);
129     FIXME("(%p)->(%p)\n", This, ppEnum);
130     return E_NOTIMPL;
131 }
132 
133 static HRESULT WINAPI OleUndoManager_EnumRedoable(IOleUndoManager *iface,
134         IEnumOleUndoUnits **ppEnum)
135 {
136     UndoManager *This = impl_from_IOleUndoManager(iface);
137     FIXME("(%p)->(%p)\n", This, ppEnum);
138     return E_NOTIMPL;
139 }
140 
141 static HRESULT WINAPI OleUndoManager_GetLastUndoDescription(IOleUndoManager *iface, BSTR *pBstr)
142 {
143     UndoManager *This = impl_from_IOleUndoManager(iface);
144     FIXME("(%p)->(%p)\n", This, pBstr);
145     return E_NOTIMPL;
146 }
147 
148 static HRESULT WINAPI OleUndoManager_GetLastRedoDescription(IOleUndoManager *iface, BSTR *pBstr)
149 {
150     UndoManager *This = impl_from_IOleUndoManager(iface);
151     FIXME("(%p)->(%p)\n", This, pBstr);
152     return E_NOTIMPL;
153 }
154 
155 static HRESULT WINAPI OleUndoManager_Enable(IOleUndoManager *iface, BOOL fEnable)
156 {
157     UndoManager *This = impl_from_IOleUndoManager(iface);
158     FIXME("(%p)->(%x)\n", This, fEnable);
159     return E_NOTIMPL;
160 }
161 
162 static const IOleUndoManagerVtbl OleUndoManagerVtbl = {
163     OleUndoManager_QueryInterface,
164     OleUndoManager_AddRef,
165     OleUndoManager_Release,
166     OleUndoManager_Open,
167     OleUndoManager_Close,
168     OleUndoManager_Add,
169     OleUndoManager_GetOpenParentState,
170     OleUndoManager_DiscardFrom,
171     OleUndoManager_UndoTo,
172     OleUndoManager_RedoTo,
173     OleUndoManager_EnumUndoable,
174     OleUndoManager_EnumRedoable,
175     OleUndoManager_GetLastUndoDescription,
176     OleUndoManager_GetLastRedoDescription,
177     OleUndoManager_Enable
178 };
179 
180 static IOleUndoManager *create_undomgr(void)
181 {
182     UndoManager *ret = heap_alloc(sizeof(UndoManager));
183 
184     if (!ret) return NULL;
185 
186     ret->IOleUndoManager_iface.lpVtbl = &OleUndoManagerVtbl;
187     ret->ref = 1;
188 
189     return &ret->IOleUndoManager_iface;
190 }
191 
192 typedef struct {
193     IHTMLEditServices IHTMLEditServices_iface;
194     LONG ref;
195 } editsvcs;
196 
197 static inline editsvcs *impl_from_IHTMLEditServices(IHTMLEditServices *iface)
198 {
199     return CONTAINING_RECORD(iface, editsvcs, IHTMLEditServices_iface);
200 }
201 
202 static HRESULT WINAPI editsvcs_QueryInterface(IHTMLEditServices *iface, REFIID riid, void **ppv)
203 {
204     editsvcs *This = impl_from_IHTMLEditServices(iface);
205 
206     TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
207 
208     if(IsEqualGUID(riid, &IID_IUnknown)) {
209         *ppv = &This->IHTMLEditServices_iface;
210     } else if(IsEqualGUID(riid, &IID_IHTMLEditServices)) {
211         *ppv = &This->IHTMLEditServices_iface;
212     } else {
213         *ppv = NULL;
214         FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
215         return E_NOINTERFACE;
216     }
217 
218     IUnknown_AddRef((IUnknown*)*ppv);
219     return S_OK;
220 }
221 
222 static ULONG WINAPI editsvcs_AddRef(IHTMLEditServices *iface)
223 {
224     editsvcs *This = impl_from_IHTMLEditServices(iface);
225     LONG ref = InterlockedIncrement(&This->ref);
226 
227     TRACE("(%p) ref=%d\n", This, ref);
228     return ref;
229 }
230 
231 static ULONG WINAPI editsvcs_Release(IHTMLEditServices *iface)
232 {
233     editsvcs *This = impl_from_IHTMLEditServices(iface);
234     LONG ref = InterlockedDecrement(&This->ref);
235 
236     TRACE("(%p) ref=%d\n", This, ref);
237 
238     if(!ref)
239         heap_free(This);
240 
241     return ref;
242 }
243 
244 static HRESULT WINAPI editsvcs_AddDesigner(IHTMLEditServices *iface,
245     IHTMLEditDesigner *pIDesigner)
246 {
247     editsvcs *This = impl_from_IHTMLEditServices(iface);
248     FIXME("(%p)->(%p)\n", This, pIDesigner);
249     return E_NOTIMPL;
250 }
251 
252 static HRESULT WINAPI editsvcs_RemoveDesigner(IHTMLEditServices *iface,
253     IHTMLEditDesigner *pIDesigner)
254 {
255     editsvcs *This = impl_from_IHTMLEditServices(iface);
256     FIXME("(%p)->(%p)\n", This, pIDesigner);
257     return E_NOTIMPL;
258 }
259 
260 static HRESULT WINAPI editsvcs_GetSelectionServices(IHTMLEditServices *iface,
261     IMarkupContainer *pIContainer, ISelectionServices **ppSelSvc)
262 {
263     editsvcs *This = impl_from_IHTMLEditServices(iface);
264     FIXME("(%p)->(%p,%p)\n", This, pIContainer, ppSelSvc);
265     return E_NOTIMPL;
266 }
267 
268 static HRESULT WINAPI editsvcs_MoveToSelectionAnchor(IHTMLEditServices *iface,
269     IMarkupPointer *pIStartAnchor)
270 {
271     editsvcs *This = impl_from_IHTMLEditServices(iface);
272     FIXME("(%p)->(%p)\n", This, pIStartAnchor);
273     return E_NOTIMPL;
274 }
275 
276 static HRESULT WINAPI editsvcs_MoveToSelectionEnd(IHTMLEditServices *iface,
277     IMarkupPointer *pIEndAnchor)
278 {
279     editsvcs *This = impl_from_IHTMLEditServices(iface);
280     FIXME("(%p)->(%p)\n", This, pIEndAnchor);
281     return E_NOTIMPL;
282 }
283 
284 static HRESULT WINAPI editsvcs_SelectRange(IHTMLEditServices *iface,
285     IMarkupPointer *pStart, IMarkupPointer *pEnd, SELECTION_TYPE eType)
286 {
287     editsvcs *This = impl_from_IHTMLEditServices(iface);
288     FIXME("(%p)->(%p,%p,%#x)\n", This, pStart, pEnd, eType);
289     return E_NOTIMPL;
290 }
291 
292 static const IHTMLEditServicesVtbl editsvcsVtbl = {
293     editsvcs_QueryInterface,
294     editsvcs_AddRef,
295     editsvcs_Release,
296     editsvcs_AddDesigner,
297     editsvcs_RemoveDesigner,
298     editsvcs_GetSelectionServices,
299     editsvcs_MoveToSelectionAnchor,
300     editsvcs_MoveToSelectionEnd,
301     editsvcs_SelectRange,
302 };
303 
304 static IHTMLEditServices *create_editsvcs(void)
305 {
306     editsvcs *ret = heap_alloc(sizeof(*ret));
307 
308     if (ret) {
309         ret->IHTMLEditServices_iface.lpVtbl = &editsvcsVtbl;
310         ret->ref = 1;
311         return &ret->IHTMLEditServices_iface;
312     }
313 
314     return NULL;
315 }
316 
317 /**********************************************************
318  * IServiceProvider implementation
319  */
320 
321 static inline HTMLDocument *impl_from_IServiceProvider(IServiceProvider *iface)
322 {
323     return CONTAINING_RECORD(iface, HTMLDocument, IServiceProvider_iface);
324 }
325 
326 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
327 {
328     HTMLDocument *This = impl_from_IServiceProvider(iface);
329     return htmldoc_query_interface(This, riid, ppv);
330 }
331 
332 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
333 {
334     HTMLDocument *This = impl_from_IServiceProvider(iface);
335     return htmldoc_addref(This);
336 }
337 
338 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
339 {
340     HTMLDocument *This = impl_from_IServiceProvider(iface);
341     return htmldoc_release(This);
342 }
343 
344 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
345         REFIID riid, void **ppv)
346 {
347     HTMLDocument *This = impl_from_IServiceProvider(iface);
348 
349     if(IsEqualGUID(&CLSID_CMarkup, guidService)) {
350         FIXME("(%p)->(CLSID_CMarkup %s %p)\n", This, debugstr_guid(riid), ppv);
351         return E_NOINTERFACE;
352     }
353 
354     if(IsEqualGUID(&SID_SOleUndoManager, guidService)) {
355         TRACE("SID_SOleUndoManager\n");
356 
357         if(!This->doc_obj->undomgr)
358             This->doc_obj->undomgr = create_undomgr();
359 
360         if (!This->doc_obj->undomgr)
361             return E_OUTOFMEMORY;
362 
363         return IOleUndoManager_QueryInterface(This->doc_obj->undomgr, riid, ppv);
364     }
365 
366     if(IsEqualGUID(&SID_SContainerDispatch, guidService)) {
367         TRACE("SID_SContainerDispatch\n");
368         return IHTMLDocument2_QueryInterface(&This->IHTMLDocument2_iface, riid, ppv);
369     }
370 
371     if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
372         TRACE("IID_IWindowForBindingUI\n");
373         return IWindowForBindingUI_QueryInterface(&This->doc_obj->IWindowForBindingUI_iface, riid, ppv);
374     }
375 
376     if(IsEqualGUID(&SID_SHTMLEditServices, guidService)) {
377         TRACE("SID_SHTMLEditServices\n");
378 
379         if(!This->doc_obj->editsvcs)
380             This->doc_obj->editsvcs = create_editsvcs();
381 
382         if (!This->doc_obj->editsvcs)
383             return E_OUTOFMEMORY;
384 
385         return IHTMLEditServices_QueryInterface(This->doc_obj->editsvcs, riid, ppv);
386     }
387 
388     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
389 
390     if(This->doc_obj->client) {
391         HRESULT hres;
392 
393         hres = do_query_service((IUnknown*)This->doc_obj->client, guidService, riid, ppv);
394         if(SUCCEEDED(hres))
395             return hres;
396     }
397 
398     FIXME("unknown service %s\n", debugstr_guid(guidService));
399     return E_NOINTERFACE;
400 }
401 
402 static const IServiceProviderVtbl ServiceProviderVtbl = {
403     ServiceProvider_QueryInterface,
404     ServiceProvider_AddRef,
405     ServiceProvider_Release,
406     ServiceProvider_QueryService
407 };
408 
409 void HTMLDocument_Service_Init(HTMLDocument *This)
410 {
411     This->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
412 }
413