htmlimg.c 27.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*
 * Copyright 2008 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"
31
#include "htmlevent.h"
32 33 34 35 36 37

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

typedef struct {
    HTMLElement element;

38
    IHTMLImgElement IHTMLImgElement_iface;
39 40

    nsIDOMHTMLImageElement *nsimg;
41 42
} HTMLImgElement;

43 44 45 46
static inline HTMLImgElement *impl_from_IHTMLImgElement(IHTMLImgElement *iface)
{
    return CONTAINING_RECORD(iface, HTMLImgElement, IHTMLImgElement_iface);
}
47 48 49

static HRESULT WINAPI HTMLImgElement_QueryInterface(IHTMLImgElement *iface, REFIID riid, void **ppv)
{
50
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
51

52
    return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
53 54 55 56
}

static ULONG WINAPI HTMLImgElement_AddRef(IHTMLImgElement *iface)
{
57
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
58

59
    return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
60 61 62 63
}

static ULONG WINAPI HTMLImgElement_Release(IHTMLImgElement *iface)
{
64
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
65

66
    return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
67 68 69 70
}

static HRESULT WINAPI HTMLImgElement_GetTypeInfoCount(IHTMLImgElement *iface, UINT *pctinfo)
{
71
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
72
    return IDispatchEx_GetTypeInfoCount(&This->element.node.dispex.IDispatchEx_iface, pctinfo);
73 74 75 76 77
}

static HRESULT WINAPI HTMLImgElement_GetTypeInfo(IHTMLImgElement *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
78
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
79 80
    return IDispatchEx_GetTypeInfo(&This->element.node.dispex.IDispatchEx_iface, iTInfo, lcid,
            ppTInfo);
81 82 83 84 85 86
}

static HRESULT WINAPI HTMLImgElement_GetIDsOfNames(IHTMLImgElement *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
87
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
88 89
    return IDispatchEx_GetIDsOfNames(&This->element.node.dispex.IDispatchEx_iface, riid, rgszNames,
            cNames, lcid, rgDispId);
90 91 92 93 94 95
}

static HRESULT WINAPI HTMLImgElement_Invoke(IHTMLImgElement *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
96
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
97 98
    return IDispatchEx_Invoke(&This->element.node.dispex.IDispatchEx_iface, dispIdMember, riid,
            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
99 100 101 102
}

static HRESULT WINAPI HTMLImgElement_put_isMap(IHTMLImgElement *iface, VARIANT_BOOL v)
{
103
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
104 105 106 107 108 109
    FIXME("(%p)->(%x)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_isMap(IHTMLImgElement *iface, VARIANT_BOOL *p)
{
110
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
111 112 113 114 115 116
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_useMap(IHTMLImgElement *iface, BSTR v)
{
117
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
118 119 120 121 122 123
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_useMap(IHTMLImgElement *iface, BSTR *p)
{
124
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
125 126 127 128 129 130
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_mimeType(IHTMLImgElement *iface, BSTR *p)
{
131
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
132 133 134 135 136 137
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_fileSize(IHTMLImgElement *iface, BSTR *p)
{
138
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
139 140 141 142 143 144
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_fileCreatedDate(IHTMLImgElement *iface, BSTR *p)
{
145
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
146 147 148 149 150 151
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_fileModifiedDate(IHTMLImgElement *iface, BSTR *p)
{
152
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
153 154 155 156 157 158
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_fileUpdatedDate(IHTMLImgElement *iface, BSTR *p)
{
159
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
160 161 162 163 164 165
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_protocol(IHTMLImgElement *iface, BSTR *p)
{
166
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
167 168 169 170 171 172
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_href(IHTMLImgElement *iface, BSTR *p)
{
173
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
174 175 176 177 178 179
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_nameProp(IHTMLImgElement *iface, BSTR *p)
{
180
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
181 182 183 184 185 186
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_border(IHTMLImgElement *iface, VARIANT v)
{
187
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
188 189 190 191 192 193
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_border(IHTMLImgElement *iface, VARIANT *p)
{
194
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
195 196 197 198
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

199
static HRESULT WINAPI HTMLImgElement_put_vspace(IHTMLImgElement *iface, LONG v)
200
{
201
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
202
    FIXME("(%p)->(%d)\n", This, v);
203 204 205
    return E_NOTIMPL;
}

206
static HRESULT WINAPI HTMLImgElement_get_vspace(IHTMLImgElement *iface, LONG *p)
207
{
208
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
209 210 211 212
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

213
static HRESULT WINAPI HTMLImgElement_put_hspace(IHTMLImgElement *iface, LONG v)
214
{
215
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
216
    FIXME("(%p)->(%d)\n", This, v);
217 218 219
    return E_NOTIMPL;
}

220
static HRESULT WINAPI HTMLImgElement_get_hspace(IHTMLImgElement *iface, LONG *p)
221
{
222
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
223 224 225 226 227 228
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_alt(IHTMLImgElement *iface, BSTR v)
{
229
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
230 231 232 233 234
    nsAString alt_str;
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

235
    nsAString_InitDepend(&alt_str, v);
236 237 238 239 240 241
    nsres = nsIDOMHTMLImageElement_SetAlt(This->nsimg, &alt_str);
    nsAString_Finish(&alt_str);
    if(NS_FAILED(nsres))
        ERR("SetAlt failed: %08x\n", nsres);

    return S_OK;
242 243 244 245
}

static HRESULT WINAPI HTMLImgElement_get_alt(IHTMLImgElement *iface, BSTR *p)
{
246
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
    nsAString alt_str;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&alt_str, NULL);
    nsres = nsIDOMHTMLImageElement_GetAlt(This->nsimg, &alt_str);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *alt;

        nsAString_GetData(&alt_str, &alt);
        *p = *alt ? SysAllocString(alt) : NULL;
    }else {
        ERR("GetAlt failed: %08x\n", nsres);
    }
    nsAString_Finish(&alt_str);

    return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
265 266 267 268
}

static HRESULT WINAPI HTMLImgElement_put_src(IHTMLImgElement *iface, BSTR v)
{
269
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
270 271 272 273 274
    nsAString src_str;
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

275
    nsAString_InitDepend(&src_str, v);
276 277 278 279 280 281
    nsres = nsIDOMHTMLImageElement_SetSrc(This->nsimg, &src_str);
    nsAString_Finish(&src_str);
    if(NS_FAILED(nsres))
        ERR("SetSrc failed: %08x\n", nsres);

    return NS_OK;
282 283 284 285
}

static HRESULT WINAPI HTMLImgElement_get_src(IHTMLImgElement *iface, BSTR *p)
{
286
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
287 288 289
    const PRUnichar *src;
    nsAString src_str;
    nsresult nsres;
290 291 292
    HRESULT hres = S_OK;

    static const WCHAR blockedW[] = {'B','L','O','C','K','E','D',':',':',0};
293 294 295 296 297

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&src_str, NULL);
    nsres = nsIDOMHTMLImageElement_GetSrc(This->nsimg, &src_str);
298 299 300 301 302 303 304 305 306 307 308 309
    if(NS_SUCCEEDED(nsres)) {
        nsAString_GetData(&src_str, &src);

        if(!strncmpiW(src, blockedW, sizeof(blockedW)/sizeof(WCHAR)-1)) {
            TRACE("returning BLOCKED::\n");
            *p = SysAllocString(blockedW);
            if(!*p)
                hres = E_OUTOFMEMORY;
        }else {
            hres = nsuri_to_url(src, TRUE, p);
        }
    }else {
310
        ERR("GetSrc failed: %08x\n", nsres);
311
        hres = E_FAIL;
312 313 314 315
    }

    nsAString_Finish(&src_str);
    return hres;
316 317 318 319
}

static HRESULT WINAPI HTMLImgElement_put_lowsrc(IHTMLImgElement *iface, BSTR v)
{
320
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
321 322 323 324 325 326
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_lowsrc(IHTMLImgElement *iface, BSTR *p)
{
327
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
328 329 330 331 332 333
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_vrml(IHTMLImgElement *iface, BSTR v)
{
334
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
335 336 337 338 339 340
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_vrml(IHTMLImgElement *iface, BSTR *p)
{
341
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
342 343 344 345 346 347
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_dynsrc(IHTMLImgElement *iface, BSTR v)
{
348
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
349 350 351 352 353 354
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_dynsrc(IHTMLImgElement *iface, BSTR *p)
{
355
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
356 357 358 359 360 361
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_readyState(IHTMLImgElement *iface, BSTR *p)
{
362
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
363 364 365 366 367 368
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_complete(IHTMLImgElement *iface, VARIANT_BOOL *p)
{
369
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
370 371 372 373 374 375
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_loop(IHTMLImgElement *iface, VARIANT v)
{
376
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
377 378 379 380 381 382
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_loop(IHTMLImgElement *iface, VARIANT *p)
{
383
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
384 385 386 387 388 389
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_align(IHTMLImgElement *iface, BSTR v)
{
390
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
391 392 393 394 395 396
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_align(IHTMLImgElement *iface, BSTR *p)
{
397
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
398 399 400 401 402 403
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_onload(IHTMLImgElement *iface, VARIANT v)
{
404
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
405 406 407 408

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_node_event(&This->element.node, EVENTID_LOAD, &v);
409 410 411 412
}

static HRESULT WINAPI HTMLImgElement_get_onload(IHTMLImgElement *iface, VARIANT *p)
{
413
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
414 415 416 417

    TRACE("(%p)->(%p)\n", This, p);

    return get_node_event(&This->element.node, EVENTID_LOAD, p);
418 419 420 421
}

static HRESULT WINAPI HTMLImgElement_put_onerror(IHTMLImgElement *iface, VARIANT v)
{
422
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
423 424 425 426 427 428
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_onerror(IHTMLImgElement *iface, VARIANT *p)
{
429
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
430 431 432 433 434 435
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_onabort(IHTMLImgElement *iface, VARIANT v)
{
436
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
437 438 439 440 441 442
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_onabort(IHTMLImgElement *iface, VARIANT *p)
{
443
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
444 445 446 447 448 449
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_name(IHTMLImgElement *iface, BSTR v)
{
450
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
451 452 453 454 455 456
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_name(IHTMLImgElement *iface, BSTR *p)
{
457
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    nsAString strName;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&strName, NULL);
    nsres = nsIDOMHTMLImageElement_GetName(This->nsimg, &strName);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *str;

        nsAString_GetData(&strName, &str);
        *p = *str ? SysAllocString(str) : NULL;
    }else {
        ERR("GetName failed: %08x\n", nsres);
    }
    nsAString_Finish(&strName);

    return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
476 477
}

478
static HRESULT WINAPI HTMLImgElement_put_width(IHTMLImgElement *iface, LONG v)
479
{
480
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
481 482 483 484 485 486 487 488 489 490 491
    nsresult nsres;

    TRACE("(%p)->(%d)\n", This, v);

    nsres = nsIDOMHTMLImageElement_SetWidth(This->nsimg, v);
    if(NS_FAILED(nsres)) {
        ERR("SetWidth failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
492 493
}

494
static HRESULT WINAPI HTMLImgElement_get_width(IHTMLImgElement *iface, LONG *p)
495
{
496
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
497
    PRUint32 width;
498 499 500 501 502 503 504 505 506 507 508 509
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsres = nsIDOMHTMLImageElement_GetWidth(This->nsimg, &width);
    if(NS_FAILED(nsres)) {
        ERR("GetWidth failed: %08x\n", nsres);
        return E_FAIL;
    }

    *p = width;
    return S_OK;
510 511
}

512
static HRESULT WINAPI HTMLImgElement_put_height(IHTMLImgElement *iface, LONG v)
513
{
514
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
515 516 517 518 519 520 521 522 523 524 525
    nsresult nsres;

    TRACE("(%p)->(%d)\n", This, v);

    nsres = nsIDOMHTMLImageElement_SetHeight(This->nsimg, v);
    if(NS_FAILED(nsres)) {
        ERR("SetHeight failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
526 527
}

528
static HRESULT WINAPI HTMLImgElement_get_height(IHTMLImgElement *iface, LONG *p)
529
{
530
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
531
    PRUint32 height;
532 533 534 535 536 537 538 539 540 541 542 543
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsres = nsIDOMHTMLImageElement_GetHeight(This->nsimg, &height);
    if(NS_FAILED(nsres)) {
        ERR("GetHeight failed: %08x\n", nsres);
        return E_FAIL;
    }

    *p = height;
    return S_OK;
544 545 546 547
}

static HRESULT WINAPI HTMLImgElement_put_start(IHTMLImgElement *iface, BSTR v)
{
548
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
549 550 551 552 553 554
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_start(IHTMLImgElement *iface, BSTR *p)
{
555
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static const IHTMLImgElementVtbl HTMLImgElementVtbl = {
    HTMLImgElement_QueryInterface,
    HTMLImgElement_AddRef,
    HTMLImgElement_Release,
    HTMLImgElement_GetTypeInfoCount,
    HTMLImgElement_GetTypeInfo,
    HTMLImgElement_GetIDsOfNames,
    HTMLImgElement_Invoke,
    HTMLImgElement_put_isMap,
    HTMLImgElement_get_isMap,
    HTMLImgElement_put_useMap,
    HTMLImgElement_get_useMap,
    HTMLImgElement_get_mimeType,
    HTMLImgElement_get_fileSize,
    HTMLImgElement_get_fileCreatedDate,
    HTMLImgElement_get_fileModifiedDate,
    HTMLImgElement_get_fileUpdatedDate,
    HTMLImgElement_get_protocol,
    HTMLImgElement_get_href,
    HTMLImgElement_get_nameProp,
    HTMLImgElement_put_border,
    HTMLImgElement_get_border,
    HTMLImgElement_put_vspace,
    HTMLImgElement_get_vspace,
    HTMLImgElement_put_hspace,
    HTMLImgElement_get_hspace,
    HTMLImgElement_put_alt,
    HTMLImgElement_get_alt,
    HTMLImgElement_put_src,
    HTMLImgElement_get_src,
    HTMLImgElement_put_lowsrc,
    HTMLImgElement_get_lowsrc,
    HTMLImgElement_put_vrml,
    HTMLImgElement_get_vrml,
    HTMLImgElement_put_dynsrc,
    HTMLImgElement_get_dynsrc,
    HTMLImgElement_get_readyState,
    HTMLImgElement_get_complete,
    HTMLImgElement_put_loop,
    HTMLImgElement_get_loop,
    HTMLImgElement_put_align,
    HTMLImgElement_get_align,
    HTMLImgElement_put_onload,
    HTMLImgElement_get_onload,
    HTMLImgElement_put_onerror,
    HTMLImgElement_get_onerror,
    HTMLImgElement_put_onabort,
    HTMLImgElement_get_onabort,
    HTMLImgElement_put_name,
    HTMLImgElement_get_name,
    HTMLImgElement_put_width,
    HTMLImgElement_get_width,
    HTMLImgElement_put_height,
    HTMLImgElement_get_height,
    HTMLImgElement_put_start,
    HTMLImgElement_get_start
};

618 619 620 621
static inline HTMLImgElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
{
    return CONTAINING_RECORD(iface, HTMLImgElement, element.node);
}
622 623 624

static HRESULT HTMLImgElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
625
    HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
626 627 628 629 630

    *ppv = NULL;

    if(IsEqualGUID(&IID_IHTMLImgElement, riid)) {
        TRACE("(%p)->(IID_IHTMLImgElement %p)\n", This, ppv);
631
        *ppv = &This->IHTMLImgElement_iface;
632 633 634 635 636 637 638 639 640 641
    }else {
        return HTMLElement_QI(&This->element.node, riid, ppv);
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static void HTMLImgElement_destructor(HTMLDOMNode *iface)
{
642
    HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
643

644 645 646
    if(This->nsimg)
        nsIDOMHTMLImageElement_Release(This->nsimg);

647 648 649
    HTMLElement_destructor(&This->element.node);
}

650 651
static HRESULT HTMLImgElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
{
652
    HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
653

654
    return IHTMLImgElement_get_readyState(&This->IHTMLImgElement_iface, p);
655 656
}

657 658
static const NodeImplVtbl HTMLImgElementImplVtbl = {
    HTMLImgElement_QI,
659
    HTMLImgElement_destructor,
660
    HTMLElement_clone,
661
    HTMLElement_get_attr_col,
662 663 664 665 666
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
667
    NULL,
668
    HTMLImgElement_get_readystate
669 670
};

671
static const tid_t HTMLImgElement_iface_tids[] = {
672
    HTMLELEMENT_TIDS,
673 674 675
    IHTMLImgElement_tid,
    0
};
676 677 678 679
static dispex_static_data_t HTMLImgElement_dispex = {
    NULL,
    DispHTMLImg_tid,
    NULL,
680
    HTMLImgElement_iface_tids
681 682
};

683
HRESULT HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
684
{
685
    HTMLImgElement *ret;
686
    nsresult nsres;
687

688 689 690 691
    ret = heap_alloc_zero(sizeof(HTMLImgElement));
    if(!ret)
        return E_OUTOFMEMORY;

692
    ret->IHTMLImgElement_iface.lpVtbl = &HTMLImgElementVtbl;
693 694
    ret->element.node.vtbl = &HTMLImgElementImplVtbl;

695
    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLImageElement, (void**)&ret->nsimg);
696
    if(NS_FAILED(nsres)) {
697
        ERR("Could not get nsIDOMHTMLImageElement: %08x\n", nsres);
698 699 700
        heap_free(ret);
        return E_FAIL;
    }
701

702
    HTMLElement_Init(&ret->element, doc, nselem, &HTMLImgElement_dispex);
703

704 705
    *elem = &ret->element;
    return S_OK;
706
}
707

708 709 710 711
static inline HTMLImageElementFactory *impl_from_IHTMLImageElementFactory(IHTMLImageElementFactory *iface)
{
    return CONTAINING_RECORD(iface, HTMLImageElementFactory, IHTMLImageElementFactory_iface);
}
712 713 714 715

static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFactory *iface,
        REFIID riid, void **ppv)
{
716
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
717 718 719 720 721

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_Unknown %p)\n", This, ppv);
722
        *ppv = &This->IHTMLImageElementFactory_iface;
723 724
    }else if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) {
        TRACE("(%p)->(IID_IHTMLImageElementFactory %p)\n", This, ppv);
725
        *ppv = &This->IHTMLImageElementFactory_iface;
726 727
    }else if(dispex_query_interface(&This->dispex, riid, ppv))
        return *ppv ? S_OK : E_NOINTERFACE;
728 729 730 731 732 733 734 735 736 737 738 739

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *iface)
{
740
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
741 742 743 744 745 746 747 748 749
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface)
{
750
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
751 752 753 754 755 756 757 758 759 760 761 762 763
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref)
        heap_free(This);

    return ref;
}

static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfoCount(IHTMLImageElementFactory *iface,
        UINT *pctinfo)
{
764
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
765 766 767 768 769 770 771
    FIXME("(%p)->(%p)\n", This, pctinfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfo(IHTMLImageElementFactory *iface,
        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
772
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
773 774 775 776 777 778 779 780
    FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImageElementFactory_GetIDsOfNames(IHTMLImageElementFactory *iface,
        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
        DISPID *rgDispId)
{
781
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
782 783 784 785 786 787 788 789 790 791
    FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames,
            cNames, lcid, rgDispId);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImageElementFactory_Invoke(IHTMLImageElementFactory *iface,
        DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
        DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
        UINT *puArgErr)
{
792
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
793 794 795 796 797
    FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return E_NOTIMPL;
}

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
static LONG var_to_size(const VARIANT *v)
{
    switch(V_VT(v)) {
    case VT_EMPTY:
        return 0;
    case VT_I4:
        return V_I4(v);
    case VT_BSTR: {
        LONG ret;
        HRESULT hres;

        hres = VarI4FromStr(V_BSTR(v), 0, 0, &ret);
        if(FAILED(hres)) {
            FIXME("VarI4FromStr failed: %08x\n", hres);
            return 0;
        }
        return ret;
    }
    default:
        FIXME("unsupported size %s\n", debugstr_variant(v));
    }
    return 0;
}

822
static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface,
823
        VARIANT width, VARIANT height, IHTMLImgElement **img_elem)
824
{
825
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
826
    IHTMLImgElement *img;
827 828
    HTMLElement *elem;
    nsIDOMHTMLElement *nselem;
829
    LONG l;
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
    HRESULT hres;

    static const PRUnichar imgW[] = {'I','M','G',0};

    TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&width),
            debugstr_variant(&height), img_elem);

    if(!This->window || !This->window->doc) {
        WARN("NULL doc\n");
        return E_UNEXPECTED;
    }

    *img_elem = NULL;

    hres = create_nselem(This->window->doc, imgW, &nselem);
    if(FAILED(hres))
        return hres;

848 849 850
    hres = HTMLElement_Create(This->window->doc, (nsIDOMNode*)nselem, FALSE, &elem);
    nsIDOMHTMLElement_Release(nselem);
    if(FAILED(hres)) {
851
        ERR("HTMLElement_Create failed\n");
852
        return hres;
853 854
    }

855 856
    hres = IHTMLElement_QueryInterface(&elem->IHTMLElement_iface, &IID_IHTMLImgElement,
            (void**)&img);
857 858 859 860 861
    if(FAILED(hres)) {
        ERR("IHTMLElement_QueryInterface failed: 0x%08x\n", hres);
        return hres;
    }

862 863 864 865 866 867
    l = var_to_size(&width);
    if(l)
        IHTMLImgElement_put_width(img, l);
    l = var_to_size(&height);
    if(l)
        IHTMLImgElement_put_height(img, l);
868

869
    *img_elem = img;
870
    return S_OK;
871 872
}

873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
static const IHTMLImageElementFactoryVtbl HTMLImageElementFactoryVtbl = {
    HTMLImageElementFactory_QueryInterface,
    HTMLImageElementFactory_AddRef,
    HTMLImageElementFactory_Release,
    HTMLImageElementFactory_GetTypeInfoCount,
    HTMLImageElementFactory_GetTypeInfo,
    HTMLImageElementFactory_GetIDsOfNames,
    HTMLImageElementFactory_Invoke,
    HTMLImageElementFactory_create
};

static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface)
{
    return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex);
}

static HRESULT HTMLImageElementFactory_value(DispatchEx *dispex, LCID lcid,
890 891 892
        WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei,
        IServiceProvider *caller)
{
893
    HTMLImageElementFactory *This = impl_from_DispatchEx(dispex);
894 895 896 897 898 899 900 901 902 903 904 905
    IHTMLImgElement *img;
    VARIANT empty, *width, *height;
    HRESULT hres;
    int argc = params->cArgs - params->cNamedArgs;

    V_VT(res) = VT_NULL;

    V_VT(&empty) = VT_EMPTY;

    width = argc >= 1 ? params->rgvarg + (params->cArgs - 1) : &empty;
    height = argc >= 2 ? params->rgvarg + (params->cArgs - 2) : &empty;

906 907
    hres = IHTMLImageElementFactory_create(&This->IHTMLImageElementFactory_iface, *width, *height,
            &img);
908 909 910 911 912 913 914 915 916
    if(FAILED(hres))
        return hres;

    V_VT(res) = VT_DISPATCH;
    V_DISPATCH(res) = (IDispatch*)img;

    return S_OK;
}

917 918 919 920 921
static const tid_t HTMLImageElementFactory_iface_tids[] = {
    IHTMLImageElementFactory_tid,
    0
};

922 923
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = {
    HTMLImageElementFactory_value,
924
    NULL,
925
    NULL,
926 927 928 929 930
    NULL
};

static dispex_static_data_t HTMLImageElementFactory_dispex = {
    &HTMLImageElementFactory_dispex_vtbl,
931 932 933 934 935
    IHTMLImageElementFactory_tid,
    NULL,
    HTMLImageElementFactory_iface_tids
};

936 937 938 939 940 941
HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow *window)
{
    HTMLImageElementFactory *ret;

    ret = heap_alloc(sizeof(HTMLImageElementFactory));

942
    ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl;
943 944 945
    ret->ref = 1;
    ret->window = window;

946 947
    init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLImageElementFactory_iface,
            &HTMLImageElementFactory_dispex);
948

949 950
    return ret;
}