winex11: Implement cursor clipping using a pointer grab.
[wine] / dlls / mshtml / omnavigator.c
1 /*
2  * Copyright 2008 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 <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29
30 #include "mshtml_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct HTMLPluginsCollection HTMLPluginsCollection;
35
36 typedef struct {
37     DispatchEx dispex;
38     IOmNavigator IOmNavigator_iface;
39
40     LONG ref;
41
42     HTMLPluginsCollection *plugins;
43 } OmNavigator;
44
45 static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface)
46 {
47     return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface);
48 }
49
50 struct HTMLPluginsCollection {
51     DispatchEx dispex;
52     IHTMLPluginsCollection IHTMLPluginsCollection_iface;
53
54     LONG ref;
55
56     OmNavigator *navigator;
57 };
58
59 static inline HTMLPluginsCollection *impl_from_IHTMLPluginsCollection(IHTMLPluginsCollection *iface)
60 {
61     return CONTAINING_RECORD(iface, HTMLPluginsCollection, IHTMLPluginsCollection_iface);
62 }
63
64 static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollection *iface, REFIID riid, void **ppv)
65 {
66     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
67
68     if(IsEqualGUID(&IID_IUnknown, riid)) {
69         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
70         *ppv = &This->IHTMLPluginsCollection_iface;
71     }else if(IsEqualGUID(&IID_IHTMLPluginsCollection, riid)) {
72         TRACE("(%p)->(IID_IHTMLPluginCollection %p)\n", This, ppv);
73         *ppv = &This->IHTMLPluginsCollection_iface;
74     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
75         return *ppv ? S_OK : E_NOINTERFACE;
76     }else {
77         *ppv = NULL;
78         WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
79         return E_NOINTERFACE;
80     }
81
82     IUnknown_AddRef((IUnknown*)*ppv);
83     return S_OK;
84 }
85
86 static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface)
87 {
88     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
89     LONG ref = InterlockedIncrement(&This->ref);
90
91     TRACE("(%p) ref=%d\n", This, ref);
92
93     return ref;
94 }
95
96 static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface)
97 {
98     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
99     LONG ref = InterlockedDecrement(&This->ref);
100
101     TRACE("(%p) ref=%d\n", This, ref);
102
103     if(!ref) {
104         if(This->navigator)
105             This->navigator->plugins = NULL;
106         release_dispex(&This->dispex);
107         heap_free(This);
108     }
109
110     return ref;
111 }
112
113 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfoCount(IHTMLPluginsCollection *iface, UINT *pctinfo)
114 {
115     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
116     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
117 }
118
119 static HRESULT WINAPI HTMLPluginsCollection_GetTypeInfo(IHTMLPluginsCollection *iface, UINT iTInfo,
120                                               LCID lcid, ITypeInfo **ppTInfo)
121 {
122     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
123     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
124 }
125
126 static HRESULT WINAPI HTMLPluginsCollection_GetIDsOfNames(IHTMLPluginsCollection *iface, REFIID riid,
127         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
128 {
129     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
130     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
131             lcid, rgDispId);
132 }
133
134 static HRESULT WINAPI HTMLPluginsCollection_Invoke(IHTMLPluginsCollection *iface, DISPID dispIdMember,
135         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
136         EXCEPINFO *pExcepInfo, UINT *puArgErr)
137 {
138     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
139     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
140             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
141 }
142
143 static HRESULT WINAPI HTMLPluginsCollection_get_length(IHTMLPluginsCollection *iface, LONG *p)
144 {
145     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
146     FIXME("(%p)->(%p)\n", This, p);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI HTMLPluginsCollection_refresh(IHTMLPluginsCollection *iface, VARIANT_BOOL reload)
151 {
152     HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface);
153     FIXME("(%p)->(%x)\n", This, reload);
154     return E_NOTIMPL;
155 }
156
157 static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = {
158     HTMLPluginsCollection_QueryInterface,
159     HTMLPluginsCollection_AddRef,
160     HTMLPluginsCollection_Release,
161     HTMLPluginsCollection_GetTypeInfoCount,
162     HTMLPluginsCollection_GetTypeInfo,
163     HTMLPluginsCollection_GetIDsOfNames,
164     HTMLPluginsCollection_Invoke,
165     HTMLPluginsCollection_get_length,
166     HTMLPluginsCollection_refresh
167 };
168
169 static const tid_t HTMLPluginsCollection_iface_tids[] = {
170     IHTMLPluginsCollection_tid,
171     0
172 };
173 static dispex_static_data_t HTMLPluginsCollection_dispex = {
174     NULL,
175     DispCPlugins_tid,
176     NULL,
177     HTMLPluginsCollection_iface_tids
178 };
179
180 static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsCollection **ret)
181 {
182     HTMLPluginsCollection *col;
183
184     col = heap_alloc_zero(sizeof(*col));
185     if(!col)
186         return E_OUTOFMEMORY;
187
188     col->IHTMLPluginsCollection_iface.lpVtbl = &HTMLPluginsCollectionVtbl;
189     col->ref = 1;
190     col->navigator = navigator;
191
192     init_dispex(&col->dispex, (IUnknown*)&col->IHTMLPluginsCollection_iface,
193                 &HTMLPluginsCollection_dispex);
194
195     *ret = col;
196     return S_OK;
197 }
198
199 static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv)
200 {
201     OmNavigator *This = impl_from_IOmNavigator(iface);
202
203     *ppv = NULL;
204
205     if(IsEqualGUID(&IID_IUnknown, riid)) {
206         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
207         *ppv = &This->IOmNavigator_iface;
208     }else if(IsEqualGUID(&IID_IOmNavigator, riid)) {
209         TRACE("(%p)->(IID_IOmNavigator %p)\n", This, ppv);
210         *ppv = &This->IOmNavigator_iface;
211     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
212         return *ppv ? S_OK : E_NOINTERFACE;
213     }
214
215     if(*ppv) {
216         IUnknown_AddRef((IUnknown*)*ppv);
217         return S_OK;
218     }
219
220     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
221     return E_NOINTERFACE;
222 }
223
224 static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface)
225 {
226     OmNavigator *This = impl_from_IOmNavigator(iface);
227     LONG ref = InterlockedIncrement(&This->ref);
228
229     TRACE("(%p) ref=%d\n", This, ref);
230
231     return ref;
232 }
233
234 static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface)
235 {
236     OmNavigator *This = impl_from_IOmNavigator(iface);
237     LONG ref = InterlockedDecrement(&This->ref);
238
239     TRACE("(%p) ref=%d\n", This, ref);
240
241     if(!ref) {
242         if(This->plugins) {
243             This->plugins->navigator = NULL;
244             IHTMLPluginsCollection_Release(&This->plugins->IHTMLPluginsCollection_iface);
245         }
246         release_dispex(&This->dispex);
247         heap_free(This);
248     }
249
250     return ref;
251 }
252
253 static HRESULT WINAPI OmNavigator_GetTypeInfoCount(IOmNavigator *iface, UINT *pctinfo)
254 {
255     OmNavigator *This = impl_from_IOmNavigator(iface);
256     FIXME("(%p)->(%p)\n", This, pctinfo);
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI OmNavigator_GetTypeInfo(IOmNavigator *iface, UINT iTInfo,
261                                               LCID lcid, ITypeInfo **ppTInfo)
262 {
263     OmNavigator *This = impl_from_IOmNavigator(iface);
264
265     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
266 }
267
268 static HRESULT WINAPI OmNavigator_GetIDsOfNames(IOmNavigator *iface, REFIID riid,
269                                                 LPOLESTR *rgszNames, UINT cNames,
270                                                 LCID lcid, DISPID *rgDispId)
271 {
272     OmNavigator *This = impl_from_IOmNavigator(iface);
273
274     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
275             lcid, rgDispId);
276 }
277
278 static HRESULT WINAPI OmNavigator_Invoke(IOmNavigator *iface, DISPID dispIdMember,
279                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
280                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
281 {
282     OmNavigator *This = impl_from_IOmNavigator(iface);
283
284     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
285             pDispParams, pVarResult, pExcepInfo, puArgErr);
286 }
287
288 static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p)
289 {
290     OmNavigator *This = impl_from_IOmNavigator(iface);
291
292     static const WCHAR mozillaW[] = {'M','o','z','i','l','l','a',0};
293
294     TRACE("(%p)->(%p)\n", This, p);
295
296     *p = SysAllocString(mozillaW);
297     return S_OK;
298 }
299
300 static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p)
301 {
302     OmNavigator *This = impl_from_IOmNavigator(iface);
303
304     static const WCHAR app_nameW[] =
305         {'M','i','c','r','o','s','o','f','t',' ',
306          'I','n','t','e','r','n','e','t',' ',
307          'E','x','p','l','o','r','e','r',0};
308
309     TRACE("(%p)->(%p)\n", This, p);
310
311     *p = SysAllocString(app_nameW);
312     if(!*p)
313         return E_OUTOFMEMORY;
314
315     return S_OK;
316 }
317
318 static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
319 {
320     OmNavigator *This = impl_from_IOmNavigator(iface);
321
322     char user_agent[512];
323     DWORD size;
324     HRESULT hres;
325
326     TRACE("(%p)->(%p)\n", This, p);
327
328     size = sizeof(user_agent);
329     hres = ObtainUserAgentString(0, user_agent, &size);
330     if(FAILED(hres))
331         return hres;
332
333     if(strncmp(user_agent, "Mozilla/", 8)) {
334         FIXME("Unsupported user agent\n");
335         return E_FAIL;
336     }
337
338     size = MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, NULL, 0);
339     *p = SysAllocStringLen(NULL, size-1);
340     if(!*p)
341         return E_OUTOFMEMORY;
342
343     MultiByteToWideChar(CP_ACP, 0, user_agent+8, -1, *p, size);
344     return S_OK;
345 }
346
347 static HRESULT WINAPI OmNavigator_get_userAgent(IOmNavigator *iface, BSTR *p)
348 {
349     OmNavigator *This = impl_from_IOmNavigator(iface);
350     char user_agent[512];
351     DWORD size;
352     HRESULT hres;
353
354     TRACE("(%p)->(%p)\n", This, p);
355
356     size = sizeof(user_agent);
357     hres = ObtainUserAgentString(0, user_agent, &size);
358     if(FAILED(hres))
359         return hres;
360
361     size = MultiByteToWideChar(CP_ACP, 0, user_agent, -1, NULL, 0);
362     *p = SysAllocStringLen(NULL, size-1);
363     if(!*p)
364         return E_OUTOFMEMORY;
365
366     MultiByteToWideChar(CP_ACP, 0, user_agent, -1, *p, size);
367     return S_OK;
368 }
369
370 static HRESULT WINAPI OmNavigator_javaEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
371 {
372     OmNavigator *This = impl_from_IOmNavigator(iface);
373
374     FIXME("(%p)->(%p) semi-stub\n", This, enabled);
375
376     *enabled = VARIANT_FALSE;
377     return S_OK;
378 }
379
380 static HRESULT WINAPI OmNavigator_taintEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
381 {
382     OmNavigator *This = impl_from_IOmNavigator(iface);
383     FIXME("(%p)->(%p)\n", This, enabled);
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI OmNavigator_get_mimeTypes(IOmNavigator *iface, IHTMLMimeTypesCollection **p)
388 {
389     OmNavigator *This = impl_from_IOmNavigator(iface);
390     FIXME("(%p)->(%p)\n", This, p);
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI OmNavigator_get_plugins(IOmNavigator *iface, IHTMLPluginsCollection **p)
395 {
396     OmNavigator *This = impl_from_IOmNavigator(iface);
397
398     TRACE("(%p)->(%p)\n", This, p);
399
400     if(!This->plugins) {
401         HRESULT hres;
402
403         hres = create_plugins_collection(This, &This->plugins);
404         if(FAILED(hres))
405             return hres;
406     }else {
407         IHTMLPluginsCollection_AddRef(&This->plugins->IHTMLPluginsCollection_iface);
408     }
409
410     *p = &This->plugins->IHTMLPluginsCollection_iface;
411     return S_OK;
412 }
413
414 static HRESULT WINAPI OmNavigator_get_cookieEnabled(IOmNavigator *iface, VARIANT_BOOL *p)
415 {
416     OmNavigator *This = impl_from_IOmNavigator(iface);
417     FIXME("(%p)->(%p)\n", This, p);
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI OmNavigator_get_opsProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
422 {
423     OmNavigator *This = impl_from_IOmNavigator(iface);
424     FIXME("(%p)->(%p)\n", This, p);
425     return E_NOTIMPL;
426 }
427
428 static HRESULT WINAPI OmNavigator_toString(IOmNavigator *iface, BSTR *String)
429 {
430     OmNavigator *This = impl_from_IOmNavigator(iface);
431
432     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
433
434     TRACE("(%p)->(%p)\n", This, String);
435
436     if(!String)
437         return E_INVALIDARG;
438
439     *String = SysAllocString(objectW);
440     return *String ? S_OK : E_OUTOFMEMORY;
441 }
442
443 static HRESULT WINAPI OmNavigator_get_cpuClass(IOmNavigator *iface, BSTR *p)
444 {
445     OmNavigator *This = impl_from_IOmNavigator(iface);
446     FIXME("(%p)->(%p)\n", This, p);
447     return E_NOTIMPL;
448 }
449
450 static HRESULT WINAPI OmNavigator_get_systemLanguage(IOmNavigator *iface, BSTR *p)
451 {
452     OmNavigator *This = impl_from_IOmNavigator(iface);
453     FIXME("(%p)->(%p)\n", This, p);
454     return E_NOTIMPL;
455 }
456
457 static HRESULT WINAPI OmNavigator_get_browserLanguage(IOmNavigator *iface, BSTR *p)
458 {
459     OmNavigator *This = impl_from_IOmNavigator(iface);
460     FIXME("(%p)->(%p)\n", This, p);
461     return E_NOTIMPL;
462 }
463
464 static HRESULT WINAPI OmNavigator_get_userLanguage(IOmNavigator *iface, BSTR *p)
465 {
466     OmNavigator *This = impl_from_IOmNavigator(iface);
467     FIXME("(%p)->(%p)\n", This, p);
468     return E_NOTIMPL;
469 }
470
471 static HRESULT WINAPI OmNavigator_get_platform(IOmNavigator *iface, BSTR *p)
472 {
473     OmNavigator *This = impl_from_IOmNavigator(iface);
474
475 #ifdef _WIN64
476     static const WCHAR platformW[] = {'W','i','n','6','4',0};
477 #else
478     static const WCHAR platformW[] = {'W','i','n','3','2',0};
479 #endif
480
481     TRACE("(%p)->(%p)\n", This, p);
482
483     *p = SysAllocString(platformW);
484     return S_OK;
485 }
486
487 static HRESULT WINAPI OmNavigator_get_appMinorVersion(IOmNavigator *iface, BSTR *p)
488 {
489     OmNavigator *This = impl_from_IOmNavigator(iface);
490     FIXME("(%p)->(%p)\n", This, p);
491     return E_NOTIMPL;
492 }
493
494 static HRESULT WINAPI OmNavigator_get_connectionSpeed(IOmNavigator *iface, LONG *p)
495 {
496     OmNavigator *This = impl_from_IOmNavigator(iface);
497     FIXME("(%p)->(%p)\n", This, p);
498     return E_NOTIMPL;
499 }
500
501 static HRESULT WINAPI OmNavigator_get_onLine(IOmNavigator *iface, VARIANT_BOOL *p)
502 {
503     OmNavigator *This = impl_from_IOmNavigator(iface);
504     FIXME("(%p)->(%p)\n", This, p);
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI OmNavigator_get_userProfile(IOmNavigator *iface, IHTMLOpsProfile **p)
509 {
510     OmNavigator *This = impl_from_IOmNavigator(iface);
511     FIXME("(%p)->(%p)\n", This, p);
512     return E_NOTIMPL;
513 }
514
515 static const IOmNavigatorVtbl OmNavigatorVtbl = {
516     OmNavigator_QueryInterface,
517     OmNavigator_AddRef,
518     OmNavigator_Release,
519     OmNavigator_GetTypeInfoCount,
520     OmNavigator_GetTypeInfo,
521     OmNavigator_GetIDsOfNames,
522     OmNavigator_Invoke,
523     OmNavigator_get_appCodeName,
524     OmNavigator_get_appName,
525     OmNavigator_get_appVersion,
526     OmNavigator_get_userAgent,
527     OmNavigator_javaEnabled,
528     OmNavigator_taintEnabled,
529     OmNavigator_get_mimeTypes,
530     OmNavigator_get_plugins,
531     OmNavigator_get_cookieEnabled,
532     OmNavigator_get_opsProfile,
533     OmNavigator_toString,
534     OmNavigator_get_cpuClass,
535     OmNavigator_get_systemLanguage,
536     OmNavigator_get_browserLanguage,
537     OmNavigator_get_userLanguage,
538     OmNavigator_get_platform,
539     OmNavigator_get_appMinorVersion,
540     OmNavigator_get_connectionSpeed,
541     OmNavigator_get_onLine,
542     OmNavigator_get_userProfile
543 };
544
545 static const tid_t OmNavigator_iface_tids[] = {
546     IOmNavigator_tid,
547     0
548 };
549 static dispex_static_data_t OmNavigator_dispex = {
550     NULL,
551     DispHTMLNavigator_tid,
552     NULL,
553     OmNavigator_iface_tids
554 };
555
556 IOmNavigator *OmNavigator_Create(void)
557 {
558     OmNavigator *ret;
559
560     ret = heap_alloc_zero(sizeof(*ret));
561     ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl;
562     ret->ref = 1;
563
564     init_dispex(&ret->dispex, (IUnknown*)&ret->IOmNavigator_iface, &OmNavigator_dispex);
565
566     return &ret->IOmNavigator_iface;
567 }