wined3d: Get rid of the GL_SUPPORT macro.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006 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 #include "wine/unicode.h"
30
31 #include "mshtml_private.h"
32 #include "htmlevent.h"
33 #include "resource.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 static struct list window_list = LIST_INIT(window_list);
38
39 static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
40 {
41     if(window->doc) {
42         abort_document_bindings(window->doc);
43         window->doc->basedoc.window = NULL;
44         htmldoc_release(&window->doc->basedoc);
45     }
46     window->doc = doc_node;
47     if(doc_node)
48         htmldoc_addref(&doc_node->basedoc);
49
50     if(window->doc_obj && window->doc_obj->basedoc.window == window) {
51         if(window->doc_obj->basedoc.doc_node)
52             htmldoc_release(&window->doc_obj->basedoc.doc_node->basedoc);
53         window->doc_obj->basedoc.doc_node = doc_node;
54         if(doc_node)
55             htmldoc_addref(&doc_node->basedoc);
56     }
57 }
58
59 nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc)
60 {
61     nsIDOMDocumentView *nsdocview;
62     nsIDOMAbstractView *nsview;
63     nsIDOMWindow *nswindow;
64     nsresult nsres;
65
66     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview);
67     nsIDOMDocument_Release(nsdoc);
68     if(NS_FAILED(nsres)) {
69         ERR("Could not get nsIDOMDocumentView iface: %08x\n", nsres);
70         return NULL;
71     }
72
73     nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview);
74     nsIDOMDocumentView_Release(nsview);
75     if(NS_FAILED(nsres)) {
76         ERR("GetDefaultView failed: %08x\n", nsres);
77         return NULL;
78     }
79
80     nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow);
81     nsIDOMAbstractView_Release(nsview);
82     if(NS_FAILED(nsres)) {
83         ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres);
84         return NULL;
85     }
86
87     return nswindow;
88 }
89
90 static void release_children(HTMLWindow *This)
91 {
92     HTMLWindow *child;
93
94     while(!list_empty(&This->children)) {
95         child = LIST_ENTRY(list_tail(&This->children), HTMLWindow, sibling_entry);
96
97         list_remove(&child->sibling_entry);
98         child->parent = NULL;
99         IHTMLWindow2_Release(HTMLWINDOW2(child));
100     }
101 }
102
103 #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
104
105 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
106 {
107     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
108
109     *ppv = NULL;
110
111     if(IsEqualGUID(&IID_IUnknown, riid)) {
112         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
113         *ppv = HTMLWINDOW2(This);
114     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
115         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
116         *ppv = HTMLWINDOW2(This);
117     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
118         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
119         *ppv = DISPATCHEX(This);
120     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
121         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
122         *ppv = HTMLWINDOW2(This);
123     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
124         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
125         *ppv = HTMLWINDOW2(This);
126     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
127         TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv);
128         *ppv = HTMLWINDOW3(This);
129     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
130         return *ppv ? S_OK : E_NOINTERFACE;
131     }
132
133     if(*ppv) {
134         IUnknown_AddRef((IUnknown*)*ppv);
135         return S_OK;
136     }
137
138     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
139     return E_NOINTERFACE;
140 }
141
142 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
143 {
144     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
145     LONG ref = InterlockedIncrement(&This->ref);
146
147     TRACE("(%p) ref=%d\n", This, ref);
148
149     return ref;
150 }
151
152 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
153 {
154     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
155     LONG ref = InterlockedDecrement(&This->ref);
156
157     TRACE("(%p) ref=%d\n", This, ref);
158
159     if(!ref) {
160         DWORD i;
161
162         remove_target_tasks(This->task_magic);
163         set_window_bscallback(This, NULL);
164         set_current_mon(This, NULL);
165         window_set_docnode(This, NULL);
166         release_children(This);
167
168         if(This->option_factory) {
169             This->option_factory->window = NULL;
170             IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory));
171         }
172
173         if(This->image_factory) {
174             This->image_factory->window = NULL;
175             IHTMLImageElementFactory_Release(HTMLIMGFACTORY(This->image_factory));
176         }
177
178         if(This->location) {
179             This->location->window = NULL;
180             IHTMLLocation_Release(HTMLLOCATION(This->location));
181         }
182
183         if(This->event_target)
184             release_event_target(This->event_target);
185         for(i=0; i < This->global_prop_cnt; i++)
186             heap_free(This->global_props[i].name);
187
188         This->window_ref->window = NULL;
189         windowref_release(This->window_ref);
190
191         heap_free(This->global_props);
192         release_script_hosts(This);
193         list_remove(&This->entry);
194         release_dispex(&This->dispex);
195         heap_free(This);
196     }
197
198     return ref;
199 }
200
201 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
202 {
203     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
204
205     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
206 }
207
208 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
209                                               LCID lcid, ITypeInfo **ppTInfo)
210 {
211     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
212
213     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
214 }
215
216 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
217                                                 LPOLESTR *rgszNames, UINT cNames,
218                                                 LCID lcid, DISPID *rgDispId)
219 {
220     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
221
222     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
223 }
224
225 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
226                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
227                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
228 {
229     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
230
231     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
232             pVarResult, pExcepInfo, puArgErr);
233 }
234
235 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
236 {
237     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
238     FIXME("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
239     return E_NOTIMPL;
240 }
241
242 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
243 {
244     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
245     nsIDOMWindowCollection *nscollection;
246     PRUint32 length;
247     nsresult nsres;
248
249     TRACE("(%p)->(%p)\n", This, p);
250
251     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nscollection);
252     if(NS_FAILED(nsres)) {
253         ERR("GetFrames failed: %08x\n", nsres);
254         return E_FAIL;
255     }
256
257     nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
258     nsIDOMWindowCollection_Release(nscollection);
259     if(NS_FAILED(nsres)) {
260         ERR("GetLength failed: %08x\n", nsres);
261         return E_FAIL;
262     }
263
264     *p = length;
265     return S_OK;
266 }
267
268 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
269 {
270     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
271     FIXME("(%p)->(%p)\n", This, p);
272     return E_NOTIMPL;
273 }
274
275 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
276 {
277     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
278     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
279     return E_NOTIMPL;
280 }
281
282 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
283 {
284     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
285     FIXME("(%p)->(%p)\n", This, p);
286     return E_NOTIMPL;
287 }
288
289 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
290 {
291     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
292     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
293     return E_NOTIMPL;
294 }
295
296 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
297 {
298     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
299     FIXME("(%p)->(%p)\n", This, p);
300     return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
304         LONG msec, VARIANT *language, LONG *timerID)
305 {
306     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
307     VARIANT expr_var;
308
309     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
310
311     V_VT(&expr_var) = VT_BSTR;
312     V_BSTR(&expr_var) = expression;
313
314     return IHTMLWindow3_setTimeout(HTMLWINDOW3(This), &expr_var, msec, language, timerID);
315 }
316
317 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
318 {
319     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
320
321     TRACE("(%p)->(%d)\n", This, timerID);
322
323     return clear_task_timer(&This->doc->basedoc, FALSE, timerID);
324 }
325
326 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
327 {
328     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
329     WCHAR wszTitle[100];
330
331     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
332
333     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
334                     sizeof(wszTitle)/sizeof(WCHAR))) {
335         WARN("Could not load message box title: %d\n", GetLastError());
336         return S_OK;
337     }
338
339     MessageBoxW(This->doc_obj->hwnd, message, wszTitle, MB_ICONWARNING);
340     return S_OK;
341 }
342
343 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
344         VARIANT_BOOL *confirmed)
345 {
346     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
347     WCHAR wszTitle[100];
348
349     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
350
351     if(!confirmed) return E_INVALIDARG;
352
353     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
354                 sizeof(wszTitle)/sizeof(WCHAR))) {
355         WARN("Could not load message box title: %d\n", GetLastError());
356         *confirmed = VARIANT_TRUE;
357         return S_OK;
358     }
359
360     if(MessageBoxW(This->doc_obj->hwnd, message, wszTitle,
361                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
362         *confirmed = VARIANT_TRUE;
363     else *confirmed = VARIANT_FALSE;
364
365     return S_OK;
366 }
367
368 typedef struct
369 {
370     BSTR message;
371     BSTR dststr;
372     VARIANT *textdata;
373 }prompt_arg;
374
375 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
376         WPARAM wparam, LPARAM lparam)
377 {
378     switch(msg)
379     {
380         case WM_INITDIALOG:
381         {
382             prompt_arg *arg = (prompt_arg*)lparam;
383             WCHAR wszTitle[100];
384
385             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
386                         sizeof(wszTitle)/sizeof(WCHAR))) {
387                 WARN("Could not load message box title: %d\n", GetLastError());
388                 EndDialog(hwnd, wparam);
389                 return FALSE;
390             }
391
392             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
393             SetWindowTextW(hwnd, wszTitle);
394             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
395             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
396             return FALSE;
397         }
398         case WM_COMMAND:
399             switch(wparam)
400             {
401                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
402                     EndDialog(hwnd, wparam);
403                     return TRUE;
404                 case MAKEWPARAM(IDOK, BN_CLICKED):
405                 {
406                     prompt_arg *arg =
407                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
408                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
409                     INT len = GetWindowTextLengthW(hwndPrompt);
410
411                     if(!arg->textdata)
412                     {
413                         EndDialog(hwnd, wparam);
414                         return TRUE;
415                     }
416
417                     V_VT(arg->textdata) = VT_BSTR;
418                     if(!len && !arg->dststr)
419                         V_BSTR(arg->textdata) = NULL;
420                     else
421                     {
422                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
423                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
424                     }
425                     EndDialog(hwnd, wparam);
426                     return TRUE;
427                 }
428             }
429             return FALSE;
430         case WM_CLOSE:
431             EndDialog(hwnd, IDCANCEL);
432             return TRUE;
433         default:
434             return FALSE;
435     }
436 }
437
438 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
439         BSTR dststr, VARIANT *textdata)
440 {
441     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
442     prompt_arg arg;
443
444     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
445
446     if(textdata) V_VT(textdata) = VT_NULL;
447
448     arg.message = message;
449     arg.dststr = dststr;
450     arg.textdata = textdata;
451
452     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
453             This->doc_obj->hwnd, prompt_dlgproc, (LPARAM)&arg);
454     return S_OK;
455 }
456
457 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
458 {
459     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
460
461     TRACE("(%p)->(%p)\n", This, p);
462
463     if(!This->image_factory)
464         This->image_factory = HTMLImageElementFactory_Create(This);
465
466     *p = HTMLIMGFACTORY(This->image_factory);
467     IHTMLImageElementFactory_AddRef(*p);
468
469     return S_OK;
470 }
471
472 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
473 {
474     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
475
476     TRACE("(%p)->(%p)\n", This, p);
477
478     if(This->location) {
479         IHTMLLocation_AddRef(HTMLLOCATION(This->location));
480     }else {
481         HRESULT hres;
482
483         hres = HTMLLocation_Create(This, &This->location);
484         if(FAILED(hres))
485             return hres;
486     }
487
488     *p = HTMLLOCATION(This->location);
489     return S_OK;
490 }
491
492 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
493 {
494     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
495     FIXME("(%p)->(%p)\n", This, p);
496     return E_NOTIMPL;
497 }
498
499 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
500 {
501     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
502     FIXME("(%p)->()\n", This);
503     return E_NOTIMPL;
504 }
505
506 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
507 {
508     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
509     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
510     return E_NOTIMPL;
511 }
512
513 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
514 {
515     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
516     FIXME("(%p)->(%p)\n", This, p);
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
521 {
522     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
523
524     TRACE("(%p)->(%p)\n", This, p);
525
526     *p = OmNavigator_Create();
527     return S_OK;
528 }
529
530 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
531 {
532     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
533     nsAString name_str;
534     nsresult nsres;
535
536     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
537
538     nsAString_Init(&name_str, v);
539     nsres = nsIDOMWindow_SetName(This->nswindow, &name_str);
540     nsAString_Finish(&name_str);
541     if(NS_FAILED(nsres))
542         ERR("SetName failed: %08x\n", nsres);
543
544     return S_OK;
545 }
546
547 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
548 {
549     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
550     nsAString name_str;
551     nsresult nsres;
552     HRESULT hres;
553
554     TRACE("(%p)->(%p)\n", This, p);
555
556     nsAString_Init(&name_str, NULL);
557     nsres = nsIDOMWindow_GetName(This->nswindow, &name_str);
558     if(NS_SUCCEEDED(nsres)) {
559         const PRUnichar *name;
560
561         nsAString_GetData(&name_str, &name);
562         if(*name) {
563             *p = SysAllocString(name);
564             hres = *p ? S_OK : E_OUTOFMEMORY;
565         }else {
566             *p = NULL;
567             hres = S_OK;
568         }
569     }else {
570         ERR("GetName failed: %08x\n", nsres);
571         hres = E_FAIL;
572     }
573     nsAString_Finish(&name_str);
574
575     return hres;
576 }
577
578 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
579 {
580     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
581     FIXME("(%p)->(%p)\n", This, p);
582     return E_NOTIMPL;
583 }
584
585 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
586          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
587 {
588     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
589     FIXME("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
590           debugstr_w(features), replace, pomWindowResult);
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
595 {
596     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
597
598     TRACE("(%p)->(%p)\n", This, p);
599
600     /* FIXME: We should return kind of proxy window here. */
601     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
602     *p = HTMLWINDOW2(This);
603     return S_OK;
604 }
605
606 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
607 {
608     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
609     FIXME("(%p)->(%p)\n", This, p);
610     return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
614 {
615     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
616
617     TRACE("(%p)->(%p)\n", This, p);
618
619     /* FIXME: We should return kind of proxy window here. */
620     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
621     *p = HTMLWINDOW2(This);
622     return S_OK;
623 }
624
625 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
626 {
627     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
628     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
629     return E_NOTIMPL;
630 }
631
632 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
633 {
634     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
635     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
636     return E_NOTIMPL;
637 }
638
639 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
640 {
641     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
642     FIXME("(%p)->(%p)\n", This, p);
643     return E_NOTIMPL;
644 }
645
646 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
647 {
648     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
649     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
650     return E_NOTIMPL;
651 }
652
653 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
654 {
655     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
656     FIXME("(%p)->(%p)\n", This, p);
657     return E_NOTIMPL;
658 }
659
660 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
661 {
662     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
663
664     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
665
666     return set_window_event(This, EVENTID_LOAD, &v);
667 }
668
669 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
670 {
671     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
672
673     TRACE("(%p)->(%p)\n", This, p);
674
675     return get_window_event(This, EVENTID_LOAD, p);
676 }
677
678 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
679 {
680     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
681
682     TRACE("(%p)->(v(%d))\n", This, V_VT(&v));
683
684     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
685 }
686
687 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
688 {
689     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
690
691     TRACE("(%p)->(%p)\n", This, p);
692
693     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
694 }
695
696 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
697 {
698     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
699     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
700     return E_NOTIMPL;
701 }
702
703 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
704 {
705     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
706     FIXME("(%p)->(%p)\n", This, p);
707     return E_NOTIMPL;
708 }
709
710 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
711 {
712     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
713     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
714     return E_NOTIMPL;
715 }
716
717 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
718 {
719     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
720     FIXME("(%p)->(%p)\n", This, p);
721     return E_NOTIMPL;
722 }
723
724 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
725 {
726     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
727     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
732 {
733     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
734     FIXME("(%p)->(%p)\n", This, p);
735     return E_NOTIMPL;
736 }
737
738 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
739 {
740     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
741     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
742     return E_NOTIMPL;
743 }
744
745 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
746 {
747     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
748     FIXME("(%p)->(%p)\n", This, p);
749     return E_NOTIMPL;
750 }
751
752 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
753 {
754     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
755     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
756     return E_NOTIMPL;
757 }
758
759 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
760 {
761     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
762     FIXME("(%p)->(%p)\n", This, p);
763     return E_NOTIMPL;
764 }
765
766 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
767 {
768     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
769
770     TRACE("(%p)->(%p)\n", This, p);
771
772     if(This->doc) {
773         /* FIXME: We should return a wrapper object here */
774         *p = HTMLDOC(&This->doc->basedoc);
775         IHTMLDocument2_AddRef(*p);
776     }else {
777         *p = NULL;
778     }
779
780     return S_OK;
781 }
782
783 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
784 {
785     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
786
787     TRACE("(%p)->(%p)\n", This, p);
788
789     if(This->event)
790         IHTMLEventObj_AddRef(This->event);
791     *p = This->event;
792     return S_OK;
793 }
794
795 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
796 {
797     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
798     FIXME("(%p)->(%p)\n", This, p);
799     return E_NOTIMPL;
800 }
801
802 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
803         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
804 {
805     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
806     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
807     return E_NOTIMPL;
808 }
809
810 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
811         BSTR features)
812 {
813     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
814     FIXME("(%p)->(%s v(%d) %s)\n", This, debugstr_w(helpURL), V_VT(&helpArg), debugstr_w(features));
815     return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
819 {
820     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
821     FIXME("(%p)->(%p)\n", This, p);
822     return E_NOTIMPL;
823 }
824
825 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
826 {
827     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
828
829     TRACE("(%p)->(%p)\n", This, p);
830
831     if(!This->option_factory)
832         This->option_factory = HTMLOptionElementFactory_Create(This);
833
834     *p = HTMLOPTFACTORY(This->option_factory);
835     IHTMLOptionElementFactory_AddRef(*p);
836
837     return S_OK;
838 }
839
840 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
841 {
842     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
843     FIXME("(%p)->()\n", This);
844     return E_NOTIMPL;
845 }
846
847 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
848 {
849     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
850     FIXME("(%p)->(%p)\n", This, p);
851     return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
855 {
856     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
857     FIXME("(%p)->()\n", This);
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
862 {
863     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
864     FIXME("(%p)->(%d %d)\n", This, x, y);
865     return E_NOTIMPL;
866 }
867
868 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
869 {
870     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
871     FIXME("(%p)->(%p)\n", This, p);
872     return E_NOTIMPL;
873 }
874
875 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
876         LONG msec, VARIANT *language, LONG *timerID)
877 {
878     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
879     VARIANT expr;
880
881     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
882
883     V_VT(&expr) = VT_BSTR;
884     V_BSTR(&expr) = expression;
885     return IHTMLWindow3_setInterval(HTMLWINDOW3(This), &expr, msec, language, timerID);
886 }
887
888 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
889 {
890     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
891
892     TRACE("(%p)->(%d)\n", This, timerID);
893
894     return clear_task_timer(&This->doc->basedoc, TRUE, timerID);
895 }
896
897 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
898 {
899     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
900     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
901     return E_NOTIMPL;
902 }
903
904 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
905 {
906     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
907     FIXME("(%p)->(%p)\n", This, p);
908     return E_NOTIMPL;
909 }
910
911 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
912         VARIANT *pvarRet)
913 {
914     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
915     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
916     return E_NOTIMPL;
917 }
918
919 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
920 {
921     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
922
923     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
924
925     TRACE("(%p)->(%p)\n", This, String);
926
927     if(!String)
928         return E_INVALIDARG;
929
930     *String = SysAllocString(objectW);
931     return *String ? S_OK : E_OUTOFMEMORY;
932 }
933
934 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
935 {
936     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
937     nsresult nsres;
938
939     TRACE("(%p)->(%d %d)\n", This, x, y);
940
941     nsres = nsIDOMWindow_ScrollBy(This->nswindow, x, y);
942     if(NS_FAILED(nsres))
943         ERR("ScrollBy failed: %08x\n", nsres);
944
945     return S_OK;
946 }
947
948 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
949 {
950     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
951     nsresult nsres;
952
953     TRACE("(%p)->(%d %d)\n", This, x, y);
954
955     nsres = nsIDOMWindow_ScrollTo(This->nswindow, x, y);
956     if(NS_FAILED(nsres))
957         ERR("ScrollTo failed: %08x\n", nsres);
958
959     return S_OK;
960 }
961
962 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
963 {
964     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
965     FIXME("(%p)->(%d %d)\n", This, x, y);
966     return E_NOTIMPL;
967 }
968
969 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
970 {
971     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
972     FIXME("(%p)->(%d %d)\n", This, x, y);
973     return E_NOTIMPL;
974 }
975
976 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
977 {
978     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
979     FIXME("(%p)->(%d %d)\n", This, x, y);
980     return E_NOTIMPL;
981 }
982
983 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
984 {
985     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
986     FIXME("(%p)->(%d %d)\n", This, x, y);
987     return E_NOTIMPL;
988 }
989
990 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
991 {
992     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
993
994     TRACE("(%p)->(%p)\n", This, p);
995
996     *p = NULL;
997
998     if(!This->doc_obj->hostui)
999         return S_OK;
1000
1001     return IDocHostUIHandler_GetExternal(This->doc_obj->hostui, p);
1002 }
1003
1004 static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
1005         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1006 {
1007     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1008     IDispatchEx *dispex;
1009     IDispatch *disp;
1010     DWORD idx;
1011     HRESULT hres;
1012
1013     idx = id - MSHTML_DISPID_CUSTOM_MIN;
1014     if(idx >= This->global_prop_cnt)
1015         return DISP_E_MEMBERNOTFOUND;
1016
1017     disp = get_script_disp(This->global_props[idx].script_host);
1018     if(!disp)
1019         return E_UNEXPECTED;
1020
1021     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1022     if(SUCCEEDED(hres)) {
1023         TRACE("%s >>>\n", debugstr_w(This->global_props[idx].name));
1024         hres = IDispatchEx_InvokeEx(dispex, This->global_props[idx].id, lcid, flags, params, res, ei, caller);
1025         if(hres == S_OK)
1026             TRACE("%s <<<\n", debugstr_w(This->global_props[idx].name));
1027         else
1028             WARN("%s <<< %08x\n", debugstr_w(This->global_props[idx].name), hres);
1029         IDispatchEx_Release(dispex);
1030     }else {
1031         FIXME("No IDispatchEx\n");
1032     }
1033
1034     IDispatch_Release(disp);
1035     return hres;
1036 }
1037
1038 #undef HTMLWINDOW2_THIS
1039
1040 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
1041     HTMLWindow2_QueryInterface,
1042     HTMLWindow2_AddRef,
1043     HTMLWindow2_Release,
1044     HTMLWindow2_GetTypeInfoCount,
1045     HTMLWindow2_GetTypeInfo,
1046     HTMLWindow2_GetIDsOfNames,
1047     HTMLWindow2_Invoke,
1048     HTMLWindow2_item,
1049     HTMLWindow2_get_length,
1050     HTMLWindow2_get_frames,
1051     HTMLWindow2_put_defaultStatus,
1052     HTMLWindow2_get_defaultStatus,
1053     HTMLWindow2_put_status,
1054     HTMLWindow2_get_status,
1055     HTMLWindow2_setTimeout,
1056     HTMLWindow2_clearTimeout,
1057     HTMLWindow2_alert,
1058     HTMLWindow2_confirm,
1059     HTMLWindow2_prompt,
1060     HTMLWindow2_get_Image,
1061     HTMLWindow2_get_location,
1062     HTMLWindow2_get_history,
1063     HTMLWindow2_close,
1064     HTMLWindow2_put_opener,
1065     HTMLWindow2_get_opener,
1066     HTMLWindow2_get_navigator,
1067     HTMLWindow2_put_name,
1068     HTMLWindow2_get_name,
1069     HTMLWindow2_get_parent,
1070     HTMLWindow2_open,
1071     HTMLWindow2_get_self,
1072     HTMLWindow2_get_top,
1073     HTMLWindow2_get_window,
1074     HTMLWindow2_navigate,
1075     HTMLWindow2_put_onfocus,
1076     HTMLWindow2_get_onfocus,
1077     HTMLWindow2_put_onblur,
1078     HTMLWindow2_get_onblur,
1079     HTMLWindow2_put_onload,
1080     HTMLWindow2_get_onload,
1081     HTMLWindow2_put_onbeforeunload,
1082     HTMLWindow2_get_onbeforeunload,
1083     HTMLWindow2_put_onunload,
1084     HTMLWindow2_get_onunload,
1085     HTMLWindow2_put_onhelp,
1086     HTMLWindow2_get_onhelp,
1087     HTMLWindow2_put_onerror,
1088     HTMLWindow2_get_onerror,
1089     HTMLWindow2_put_onresize,
1090     HTMLWindow2_get_onresize,
1091     HTMLWindow2_put_onscroll,
1092     HTMLWindow2_get_onscroll,
1093     HTMLWindow2_get_document,
1094     HTMLWindow2_get_event,
1095     HTMLWindow2_get__newEnum,
1096     HTMLWindow2_showModalDialog,
1097     HTMLWindow2_showHelp,
1098     HTMLWindow2_get_screen,
1099     HTMLWindow2_get_Option,
1100     HTMLWindow2_focus,
1101     HTMLWindow2_get_closed,
1102     HTMLWindow2_blur,
1103     HTMLWindow2_scroll,
1104     HTMLWindow2_get_clientInformation,
1105     HTMLWindow2_setInterval,
1106     HTMLWindow2_clearInterval,
1107     HTMLWindow2_put_offscreenBuffering,
1108     HTMLWindow2_get_offscreenBuffering,
1109     HTMLWindow2_execScript,
1110     HTMLWindow2_toString,
1111     HTMLWindow2_scrollBy,
1112     HTMLWindow2_scrollTo,
1113     HTMLWindow2_moveTo,
1114     HTMLWindow2_moveBy,
1115     HTMLWindow2_resizeTo,
1116     HTMLWindow2_resizeBy,
1117     HTMLWindow2_get_external
1118 };
1119
1120 #define HTMLWINDOW3_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow3, iface)
1121
1122 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
1123 {
1124     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1125
1126     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1127 }
1128
1129 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
1130 {
1131     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1132
1133     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1134 }
1135
1136 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
1137 {
1138     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1139
1140     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1141 }
1142
1143 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
1144 {
1145     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1146
1147     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
1148 }
1149
1150 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
1151                                               LCID lcid, ITypeInfo **ppTInfo)
1152 {
1153     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1154
1155     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
1156 }
1157
1158 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
1159                                                 LPOLESTR *rgszNames, UINT cNames,
1160                                                 LCID lcid, DISPID *rgDispId)
1161 {
1162     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1163
1164     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
1165 }
1166
1167 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
1168                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1169                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1170 {
1171     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1172
1173     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
1174             pVarResult, pExcepInfo, puArgErr);
1175 }
1176
1177 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
1178 {
1179     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1180     FIXME("(%p)->(%p)\n", This, p);
1181     return E_NOTIMPL;
1182 }
1183
1184 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
1185 {
1186     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1187     FIXME("(%p)->(%p)\n", This, p);
1188     return E_NOTIMPL;
1189 }
1190
1191 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
1192 {
1193     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1194
1195     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1196
1197     return attach_event(&This->event_target, &This->doc_obj->basedoc, event, pDisp, pfResult);
1198 }
1199
1200 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1201 {
1202     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1203     FIXME("(%p)->()\n", This);
1204     return E_NOTIMPL;
1205 }
1206
1207 static HRESULT window_set_timer(HTMLWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1208         BOOL interval, LONG *timer_id)
1209 {
1210     IDispatch *disp = NULL;
1211
1212     switch(V_VT(expr)) {
1213     case VT_DISPATCH:
1214         disp = V_DISPATCH(expr);
1215         IDispatch_AddRef(disp);
1216         break;
1217
1218     case VT_BSTR:
1219         disp = script_parse_event(This, V_BSTR(expr));
1220         break;
1221
1222     default:
1223         FIXME("unimplemented vt=%d\n", V_VT(expr));
1224         return E_NOTIMPL;
1225     }
1226
1227     if(!disp)
1228         return E_FAIL;
1229
1230     *timer_id = set_task_timer(&This->doc->basedoc, msec, interval, disp);
1231     IDispatch_Release(disp);
1232
1233     return S_OK;
1234 }
1235
1236 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1237         VARIANT *language, LONG *timerID)
1238 {
1239     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1240
1241     TRACE("(%p)->(%p(%d) %d %p %p)\n", This, expression, V_VT(expression), msec, language, timerID);
1242
1243     return window_set_timer(This, expression, msec, language, FALSE, timerID);
1244 }
1245
1246 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1247         VARIANT *language, LONG *timerID)
1248 {
1249     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1250
1251     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1252
1253     return window_set_timer(This, expression, msec, language, TRUE, timerID);
1254 }
1255
1256 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1257 {
1258     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1259     FIXME("(%p)\n", This);
1260     return E_NOTIMPL;
1261 }
1262
1263 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1264 {
1265     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1266     FIXME("(%p)->()\n", This);
1267     return E_NOTIMPL;
1268 }
1269
1270 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1271 {
1272     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1273     FIXME("(%p)->(%p)\n", This, p);
1274     return E_NOTIMPL;
1275 }
1276
1277 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1278 {
1279     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1280     FIXME("(%p)->()\n", This);
1281     return E_NOTIMPL;
1282 }
1283
1284 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1285 {
1286     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1287     FIXME("(%p)->(%p)\n", This, p);
1288     return E_NOTIMPL;
1289 }
1290
1291 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1292 {
1293     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1294     FIXME("(%p)->(%p)\n", This, p);
1295     return E_NOTIMPL;
1296 }
1297
1298 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1299         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1300 {
1301     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1302     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1303     return E_NOTIMPL;
1304 }
1305
1306 #undef HTMLWINDOW3_THIS
1307
1308 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1309     HTMLWindow3_QueryInterface,
1310     HTMLWindow3_AddRef,
1311     HTMLWindow3_Release,
1312     HTMLWindow3_GetTypeInfoCount,
1313     HTMLWindow3_GetTypeInfo,
1314     HTMLWindow3_GetIDsOfNames,
1315     HTMLWindow3_Invoke,
1316     HTMLWindow3_get_screenLeft,
1317     HTMLWindow3_get_screenTop,
1318     HTMLWindow3_attachEvent,
1319     HTMLWindow3_detachEvent,
1320     HTMLWindow3_setTimeout,
1321     HTMLWindow3_setInterval,
1322     HTMLWindow3_print,
1323     HTMLWindow3_put_onbeforeprint,
1324     HTMLWindow3_get_onbeforeprint,
1325     HTMLWindow3_put_onafterprint,
1326     HTMLWindow3_get_onafterprint,
1327     HTMLWindow3_get_clipboardData,
1328     HTMLWindow3_showModelessDialog
1329 };
1330
1331 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLWindow, IDispatchEx, iface)
1332
1333 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1334 {
1335     HTMLWindow *This = DISPEX_THIS(iface);
1336
1337     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1338 }
1339
1340 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
1341 {
1342     HTMLWindow *This = DISPEX_THIS(iface);
1343
1344     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1345 }
1346
1347 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
1348 {
1349     HTMLWindow *This = DISPEX_THIS(iface);
1350
1351     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1352 }
1353
1354 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1355 {
1356     HTMLWindow *This = DISPEX_THIS(iface);
1357
1358     TRACE("(%p)->(%p)\n", This, pctinfo);
1359
1360     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1361 }
1362
1363 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1364                                                LCID lcid, ITypeInfo **ppTInfo)
1365 {
1366     HTMLWindow *This = DISPEX_THIS(iface);
1367
1368     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1369
1370     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1371 }
1372
1373 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1374                                                  LPOLESTR *rgszNames, UINT cNames,
1375                                                  LCID lcid, DISPID *rgDispId)
1376 {
1377     HTMLWindow *This = DISPEX_THIS(iface);
1378
1379     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1380           lcid, rgDispId);
1381
1382     /* FIXME: Use script dispatch */
1383
1384     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
1385 }
1386
1387 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1388                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1389                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1390 {
1391     HTMLWindow *This = DISPEX_THIS(iface);
1392
1393     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1394           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1395
1396     /* FIXME: Use script dispatch */
1397
1398     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
1399                               pVarResult, pExcepInfo, puArgErr);
1400 }
1401
1402 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1403 {
1404     HTMLWindow *This = DISPEX_THIS(iface);
1405     ScriptHost *script_host;
1406     DISPID id;
1407     DWORD i;
1408
1409     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
1410
1411     for(i=0; i < This->global_prop_cnt; i++) {
1412         /* FIXME: case sensitivity */
1413         if(!strcmpW(This->global_props[i].name, bstrName)) {
1414             *pid = MSHTML_DISPID_CUSTOM_MIN+i;
1415             return S_OK;
1416         }
1417     }
1418
1419     if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
1420         if(This->global_prop_cnt == This->global_prop_size) {
1421             global_prop_t *new_props;
1422             DWORD new_size;
1423
1424             if(This->global_props) {
1425                 new_size = This->global_prop_size*2;
1426                 new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
1427             }else {
1428                 new_size = 16;
1429                 new_props = heap_alloc(new_size*sizeof(global_prop_t));
1430             }
1431             if(!new_props)
1432                 return E_OUTOFMEMORY;
1433             This->global_props = new_props;
1434             This->global_prop_size = new_size;
1435         }
1436
1437         This->global_props[This->global_prop_cnt].name = heap_strdupW(bstrName);
1438         if(!This->global_props[This->global_prop_cnt].name)
1439             return E_OUTOFMEMORY;
1440
1441         This->global_props[This->global_prop_cnt].script_host = script_host;
1442         This->global_props[This->global_prop_cnt].id = id;
1443
1444         *pid = MSHTML_DISPID_CUSTOM_MIN + (This->global_prop_cnt++);
1445         return S_OK;
1446     }
1447
1448     return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
1449 }
1450
1451 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1452         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1453 {
1454     HTMLWindow *This = DISPEX_THIS(iface);
1455
1456     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1457
1458     return IDispatchEx_InvokeEx(DISPATCHEX(&This->dispex), id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1459 }
1460
1461 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1462 {
1463     HTMLWindow *This = DISPEX_THIS(iface);
1464
1465     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
1466
1467     return IDispatchEx_DeleteMemberByName(DISPATCHEX(&This->dispex), bstrName, grfdex);
1468 }
1469
1470 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1471 {
1472     HTMLWindow *This = DISPEX_THIS(iface);
1473
1474     TRACE("(%p)->(%x)\n", This, id);
1475
1476     return IDispatchEx_DeleteMemberByDispID(DISPATCHEX(&This->dispex), id);
1477 }
1478
1479 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1480 {
1481     HTMLWindow *This = DISPEX_THIS(iface);
1482
1483     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1484
1485     return IDispatchEx_GetMemberProperties(DISPATCHEX(&This->dispex), id, grfdexFetch, pgrfdex);
1486 }
1487
1488 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1489 {
1490     HTMLWindow *This = DISPEX_THIS(iface);
1491
1492     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
1493
1494     return IDispatchEx_GetMemberName(DISPATCHEX(&This->dispex), id, pbstrName);
1495 }
1496
1497 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1498 {
1499     HTMLWindow *This = DISPEX_THIS(iface);
1500
1501     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
1502
1503     return IDispatchEx_GetNextDispID(DISPATCHEX(&This->dispex), grfdex, id, pid);
1504 }
1505
1506 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1507 {
1508     HTMLWindow *This = DISPEX_THIS(iface);
1509
1510     TRACE("(%p)->(%p)\n", This, ppunk);
1511
1512     *ppunk = NULL;
1513     return S_OK;
1514 }
1515
1516 #undef DISPEX_THIS
1517
1518 static const IDispatchExVtbl WindowDispExVtbl = {
1519     WindowDispEx_QueryInterface,
1520     WindowDispEx_AddRef,
1521     WindowDispEx_Release,
1522     WindowDispEx_GetTypeInfoCount,
1523     WindowDispEx_GetTypeInfo,
1524     WindowDispEx_GetIDsOfNames,
1525     WindowDispEx_Invoke,
1526     WindowDispEx_GetDispID,
1527     WindowDispEx_InvokeEx,
1528     WindowDispEx_DeleteMemberByName,
1529     WindowDispEx_DeleteMemberByDispID,
1530     WindowDispEx_GetMemberProperties,
1531     WindowDispEx_GetMemberName,
1532     WindowDispEx_GetNextDispID,
1533     WindowDispEx_GetNameSpaceParent
1534 };
1535
1536 static const tid_t HTMLWindow_iface_tids[] = {
1537     IHTMLWindow2_tid,
1538     IHTMLWindow3_tid,
1539     0
1540 };
1541
1542 static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
1543     NULL,
1544     NULL,
1545     HTMLWindow_invoke
1546 };
1547
1548 static dispex_static_data_t HTMLWindow_dispex = {
1549     &HTMLWindow_dispex_vtbl,
1550     DispHTMLWindow2_tid,
1551     NULL,
1552     HTMLWindow_iface_tids
1553 };
1554
1555 HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTMLWindow *parent, HTMLWindow **ret)
1556 {
1557     HTMLWindow *window;
1558
1559     window = heap_alloc_zero(sizeof(HTMLWindow));
1560     if(!window)
1561         return E_OUTOFMEMORY;
1562
1563     window->window_ref = heap_alloc(sizeof(windowref_t));
1564     if(!window->window_ref) {
1565         heap_free(window->window_ref);
1566         return E_OUTOFMEMORY;
1567     }
1568
1569     window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl;
1570     window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl;
1571     window->lpIDispatchExVtbl = &WindowDispExVtbl;
1572     window->ref = 1;
1573     window->doc_obj = doc_obj;
1574
1575     window->window_ref->window = window;
1576     window->window_ref->ref = 1;
1577
1578     init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex);
1579
1580     if(nswindow) {
1581         nsIDOMWindow_AddRef(nswindow);
1582         window->nswindow = nswindow;
1583     }
1584
1585     window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO;
1586     list_init(&window->script_hosts);
1587
1588     window->task_magic = get_task_target_magic();
1589     update_window_doc(window);
1590
1591     list_init(&window->children);
1592     list_add_head(&window_list, &window->entry);
1593
1594     if(parent) {
1595         IHTMLWindow2_AddRef(HTMLWINDOW2(window));
1596
1597         window->parent = parent;
1598         list_add_tail(&parent->children, &window->sibling_entry);
1599     }
1600
1601     *ret = window;
1602     return S_OK;
1603 }
1604
1605 void update_window_doc(HTMLWindow *window)
1606 {
1607     nsIDOMHTMLDocument *nshtmldoc;
1608     nsIDOMDocument *nsdoc;
1609     nsresult nsres;
1610
1611     nsres = nsIDOMWindow_GetDocument(window->nswindow, &nsdoc);
1612     if(NS_FAILED(nsres) || !nsdoc) {
1613         ERR("GetDocument failed: %08x\n", nsres);
1614         return;
1615     }
1616
1617     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
1618     nsIDOMDocument_Release(nsdoc);
1619     if(NS_FAILED(nsres)) {
1620         ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
1621         return;
1622     }
1623
1624     if(!window->doc || window->doc->nsdoc != nshtmldoc) {
1625         HTMLDocumentNode *doc;
1626         HRESULT hres;
1627
1628         hres = create_doc_from_nsdoc(nshtmldoc, window->doc_obj, window, &doc);
1629         if(SUCCEEDED(hres)) {
1630             window_set_docnode(window, doc);
1631             htmldoc_release(&doc->basedoc);
1632         }else {
1633             ERR("create_doc_from_nsdoc failed: %08x\n", hres);
1634         }
1635     }
1636
1637     nsIDOMHTMLDocument_Release(nshtmldoc);
1638 }
1639
1640 HTMLWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
1641 {
1642     HTMLWindow *iter;
1643
1644     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLWindow, entry) {
1645         if(iter->nswindow == nswindow)
1646             return iter;
1647     }
1648
1649     return NULL;
1650 }