htmlimg.c 27.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * 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>
20
#include <assert.h>
21 22 23 24 25 26 27 28 29 30 31

#define COBJMACROS

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

#include "wine/debug.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

typedef struct {
    HTMLElement element;

39
    IHTMLImgElement IHTMLImgElement_iface;
40 41

    nsIDOMHTMLImageElement *nsimg;
42 43
} HTMLImgElement;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return S_OK;
243 244 245 246
}

static HRESULT WINAPI HTMLImgElement_get_alt(IHTMLImgElement *iface, BSTR *p)
{
247
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
248 249 250 251 252 253 254
    nsAString alt_str;
    nsresult nsres;

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

    nsAString_Init(&alt_str, NULL);
    nsres = nsIDOMHTMLImageElement_GetAlt(This->nsimg, &alt_str);
255
    return return_nsstr(nsres, &alt_str, p);
256 257 258 259
}

static HRESULT WINAPI HTMLImgElement_put_src(IHTMLImgElement *iface, BSTR v)
{
260
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
261 262 263 264 265
    nsAString src_str;
    nsresult nsres;

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

266
    nsAString_InitDepend(&src_str, v);
267 268 269 270 271 272
    nsres = nsIDOMHTMLImageElement_SetSrc(This->nsimg, &src_str);
    nsAString_Finish(&src_str);
    if(NS_FAILED(nsres))
        ERR("SetSrc failed: %08x\n", nsres);

    return NS_OK;
273 274 275 276
}

static HRESULT WINAPI HTMLImgElement_get_src(IHTMLImgElement *iface, BSTR *p)
{
277
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
278 279 280
    const PRUnichar *src;
    nsAString src_str;
    nsresult nsres;
281 282 283
    HRESULT hres = S_OK;

    static const WCHAR blockedW[] = {'B','L','O','C','K','E','D',':',':',0};
284 285 286 287 288

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

    nsAString_Init(&src_str, NULL);
    nsres = nsIDOMHTMLImageElement_GetSrc(This->nsimg, &src_str);
289 290 291 292 293 294 295 296 297 298 299 300
    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 {
301
        ERR("GetSrc failed: %08x\n", nsres);
302
        hres = E_FAIL;
303 304 305 306
    }

    nsAString_Finish(&src_str);
    return hres;
307 308 309 310
}

static HRESULT WINAPI HTMLImgElement_put_lowsrc(IHTMLImgElement *iface, BSTR v)
{
311
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
312 313 314 315 316 317
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_lowsrc(IHTMLImgElement *iface, BSTR *p)
{
318
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
319 320 321 322 323 324
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_vrml(IHTMLImgElement *iface, BSTR v)
{
325
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
326 327 328 329 330 331
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_vrml(IHTMLImgElement *iface, BSTR *p)
{
332
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
333 334 335 336 337 338
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_put_dynsrc(IHTMLImgElement *iface, BSTR v)
{
339
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
340 341 342 343 344 345
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_dynsrc(IHTMLImgElement *iface, BSTR *p)
{
346
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
347 348 349 350 351 352
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

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

static HRESULT WINAPI HTMLImgElement_get_complete(IHTMLImgElement *iface, VARIANT_BOOL *p)
{
360
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
361 362 363 364 365 366 367 368 369 370 371 372 373
    cpp_bool complete;
    nsresult nsres;

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

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

    *p = complete ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
374 375 376 377
}

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

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

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

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

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

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

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

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

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

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

static HRESULT WINAPI HTMLImgElement_put_onerror(IHTMLImgElement *iface, VARIANT v)
{
424
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
425 426 427 428

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

    return set_node_event(&This->element.node, EVENTID_ERROR, &v);
429 430 431 432
}

static HRESULT WINAPI HTMLImgElement_get_onerror(IHTMLImgElement *iface, VARIANT *p)
{
433
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
434 435 436 437

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

    return get_node_event(&This->element.node, EVENTID_ERROR, p);
438 439 440 441
}

static HRESULT WINAPI HTMLImgElement_put_onabort(IHTMLImgElement *iface, VARIANT v)
{
442
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
443 444 445 446

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

    return set_node_event(&This->element.node, EVENTID_ABORT, &v);
447 448 449 450
}

static HRESULT WINAPI HTMLImgElement_get_onabort(IHTMLImgElement *iface, VARIANT *p)
{
451
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
452 453 454 455

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

    return get_node_event(&This->element.node, EVENTID_ABORT, p);
456 457 458 459
}

static HRESULT WINAPI HTMLImgElement_put_name(IHTMLImgElement *iface, BSTR v)
{
460
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
461 462 463 464 465 466
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImgElement_get_name(IHTMLImgElement *iface, BSTR *p)
{
467
    HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
468
    nsAString name;
469 470 471 472
    nsresult nsres;

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

473 474 475
    nsAString_Init(&name, NULL);
    nsres = nsIDOMHTMLImageElement_GetName(This->nsimg, &name);
    return return_nsstr(nsres, &name, p);
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
    UINT32 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
    UINT32 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
    }else {
        return HTMLElement_QI(&This->element.node, riid, ppv);
    }

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

640 641
static HRESULT HTMLImgElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
{
642
    HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
643

644
    return IHTMLImgElement_get_readyState(&This->IHTMLImgElement_iface, p);
645 646
}

647 648
static const NodeImplVtbl HTMLImgElementImplVtbl = {
    HTMLImgElement_QI,
649
    HTMLElement_destructor,
650
    HTMLElement_cpc,
651
    HTMLElement_clone,
652
    HTMLElement_handle_event,
653
    HTMLElement_get_attr_col,
654 655 656 657 658 659
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    HTMLImgElement_get_readystate
660 661
};

662
static const tid_t HTMLImgElement_iface_tids[] = {
663
    HTMLELEMENT_TIDS,
664 665 666
    IHTMLImgElement_tid,
    0
};
667 668 669 670
static dispex_static_data_t HTMLImgElement_dispex = {
    NULL,
    DispHTMLImg_tid,
    NULL,
671
    HTMLImgElement_iface_tids
672 673
};

674
HRESULT HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
675
{
676
    HTMLImgElement *ret;
677
    nsresult nsres;
678

679 680 681 682
    ret = heap_alloc_zero(sizeof(HTMLImgElement));
    if(!ret)
        return E_OUTOFMEMORY;

683
    ret->IHTMLImgElement_iface.lpVtbl = &HTMLImgElementVtbl;
684 685
    ret->element.node.vtbl = &HTMLImgElementImplVtbl;

686 687
    HTMLElement_Init(&ret->element, doc, nselem, &HTMLImgElement_dispex);

688 689
    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLImageElement, (void**)&ret->nsimg);

690 691 692
    /* Share nsimg reference with nsnode */
    assert(nsres == NS_OK && (nsIDOMNode*)ret->nsimg == ret->element.node.nsnode);
    nsIDOMNode_Release(ret->element.node.nsnode);
693

694 695
    *elem = &ret->element;
    return S_OK;
696
}
697

698 699 700 701
static inline HTMLImageElementFactory *impl_from_IHTMLImageElementFactory(IHTMLImageElementFactory *iface)
{
    return CONTAINING_RECORD(iface, HTMLImageElementFactory, IHTMLImageElementFactory_iface);
}
702 703 704 705

static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFactory *iface,
        REFIID riid, void **ppv)
{
706
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
707 708 709 710 711

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_Unknown %p)\n", This, ppv);
712
        *ppv = &This->IHTMLImageElementFactory_iface;
713 714
    }else if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) {
        TRACE("(%p)->(IID_IHTMLImageElementFactory %p)\n", This, ppv);
715
        *ppv = &This->IHTMLImageElementFactory_iface;
716 717
    }else if(dispex_query_interface(&This->dispex, riid, ppv))
        return *ppv ? S_OK : E_NOINTERFACE;
718 719 720 721 722 723 724 725 726 727 728 729

    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)
{
730
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
731 732 733 734 735 736 737 738 739
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface)
{
740
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
741 742 743 744 745 746 747 748 749 750 751 752 753
    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)
{
754
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
755 756 757 758 759 760 761
    FIXME("(%p)->(%p)\n", This, pctinfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfo(IHTMLImageElementFactory *iface,
        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
762
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
763 764 765 766 767 768 769 770
    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)
{
771
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
772 773 774 775 776 777 778 779 780 781
    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)
{
782
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
783 784 785 786 787
    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;
}

788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
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;
}

812
static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface,
813
        VARIANT width, VARIANT height, IHTMLImgElement **img_elem)
814
{
815
    HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
816
    HTMLDocumentNode *doc;
817
    IHTMLImgElement *img;
818 819
    HTMLElement *elem;
    nsIDOMHTMLElement *nselem;
820
    LONG l;
821 822 823 824 825 826 827
    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);

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

833
    doc = This->window->doc;
834

835 836
    *img_elem = NULL;

837
    hres = create_nselem(doc, imgW, &nselem);
838 839 840
    if(FAILED(hres))
        return hres;

841
    hres = HTMLElement_Create(doc, (nsIDOMNode*)nselem, FALSE, &elem);
842 843
    nsIDOMHTMLElement_Release(nselem);
    if(FAILED(hres)) {
844
        ERR("HTMLElement_Create failed\n");
845
        return hres;
846 847
    }

848 849
    hres = IHTMLElement_QueryInterface(&elem->IHTMLElement_iface, &IID_IHTMLImgElement,
            (void**)&img);
850
    IHTMLElement_Release(&elem->IHTMLElement_iface);
851 852 853 854 855
    if(FAILED(hres)) {
        ERR("IHTMLElement_QueryInterface failed: 0x%08x\n", hres);
        return hres;
    }

856 857 858 859 860 861
    l = var_to_size(&width);
    if(l)
        IHTMLImgElement_put_width(img, l);
    l = var_to_size(&height);
    if(l)
        IHTMLImgElement_put_height(img, l);
862

863
    *img_elem = img;
864
    return S_OK;
865 866
}

867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
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,
884 885 886
        WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei,
        IServiceProvider *caller)
{
887
    HTMLImageElementFactory *This = impl_from_DispatchEx(dispex);
888 889 890 891 892 893 894 895 896 897 898 899
    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;

900 901
    hres = IHTMLImageElementFactory_create(&This->IHTMLImageElementFactory_iface, *width, *height,
            &img);
902 903 904 905 906 907 908 909 910
    if(FAILED(hres))
        return hres;

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

    return S_OK;
}

911 912 913 914 915
static const tid_t HTMLImageElementFactory_iface_tids[] = {
    IHTMLImageElementFactory_tid,
    0
};

916 917
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = {
    HTMLImageElementFactory_value,
918
    NULL,
919
    NULL,
920 921 922 923 924
    NULL
};

static dispex_static_data_t HTMLImageElementFactory_dispex = {
    &HTMLImageElementFactory_dispex_vtbl,
925 926 927 928 929
    IHTMLImageElementFactory_tid,
    NULL,
    HTMLImageElementFactory_iface_tids
};

930
HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, HTMLImageElementFactory **ret_val)
931 932 933 934
{
    HTMLImageElementFactory *ret;

    ret = heap_alloc(sizeof(HTMLImageElementFactory));
935 936
    if(!ret)
        return E_OUTOFMEMORY;
937

938
    ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl;
939 940 941
    ret->ref = 1;
    ret->window = window;

942 943
    init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLImageElementFactory_iface,
            &HTMLImageElementFactory_dispex);
944

945 946
    *ret_val = ret;
    return S_OK;
947
}