mshtml: COM cleanup for the IHTMLDOMNode iface.
[wine] / dlls / mshtml / htmltextarea.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
30 #include "mshtml_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct {
35     HTMLElement element;
36
37     IHTMLTextAreaElement IHTMLTextAreaElement_iface;
38
39     nsIDOMHTMLTextAreaElement *nstextarea;
40 } HTMLTextAreaElement;
41
42 static inline HTMLTextAreaElement *impl_from_IHTMLTextAreaElement(IHTMLTextAreaElement *iface)
43 {
44     return CONTAINING_RECORD(iface, HTMLTextAreaElement, IHTMLTextAreaElement_iface);
45 }
46
47 static HRESULT WINAPI HTMLTextAreaElement_QueryInterface(IHTMLTextAreaElement *iface,
48                                                          REFIID riid, void **ppv)
49 {
50     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
51
52     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
53 }
54
55 static ULONG WINAPI HTMLTextAreaElement_AddRef(IHTMLTextAreaElement *iface)
56 {
57     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
58
59     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
60 }
61
62 static ULONG WINAPI HTMLTextAreaElement_Release(IHTMLTextAreaElement *iface)
63 {
64     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
65
66     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
67 }
68
69 static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfoCount(IHTMLTextAreaElement *iface, UINT *pctinfo)
70 {
71     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
72     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfo(IHTMLTextAreaElement *iface, UINT iTInfo,
76                                               LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
79     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo);
80 }
81
82 static HRESULT WINAPI HTMLTextAreaElement_GetIDsOfNames(IHTMLTextAreaElement *iface, REFIID riid,
83                                                 LPOLESTR *rgszNames, UINT cNames,
84                                                 LCID lcid, DISPID *rgDispId)
85 {
86     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
87     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
88 }
89
90 static HRESULT WINAPI HTMLTextAreaElement_Invoke(IHTMLTextAreaElement *iface, DISPID dispIdMember,
91                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
92                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
93 {
94     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
95     return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
96             pVarResult, pExcepInfo, puArgErr);
97 }
98
99 static HRESULT WINAPI HTMLTextAreaElement_get_type(IHTMLTextAreaElement *iface, BSTR *p)
100 {
101     static const WCHAR textareaW[] = {'t','e','x','t','a','r','e','a',0};
102
103     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
104
105     TRACE("(%p)->(%p)\n", This, p);
106
107     *p = SysAllocString(textareaW);
108     if(!*p)
109         return E_OUTOFMEMORY;
110     return S_OK;
111 }
112
113 static HRESULT WINAPI HTMLTextAreaElement_put_value(IHTMLTextAreaElement *iface, BSTR v)
114 {
115     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
116     nsAString value_str;
117     nsresult nsres;
118
119     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
120
121     nsAString_InitDepend(&value_str, v);
122     nsres = nsIDOMHTMLTextAreaElement_SetValue(This->nstextarea, &value_str);
123     nsAString_Finish(&value_str);
124     if(NS_FAILED(nsres)) {
125         ERR("SetValue failed: %08x\n", nsres);
126         return E_FAIL;
127     }
128
129     return S_OK;
130 }
131
132 static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, BSTR *p)
133 {
134     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
135     nsAString value_str;
136     const PRUnichar *value;
137     nsresult nsres;
138     HRESULT hres = S_OK;
139
140     TRACE("(%p)->(%p)\n", This, p);
141
142     nsAString_Init(&value_str, NULL);
143
144     nsres = nsIDOMHTMLTextAreaElement_GetValue(This->nstextarea, &value_str);
145     if(NS_SUCCEEDED(nsres)) {
146         nsAString_GetData(&value_str, &value);
147         *p = *value ? SysAllocString(value) : NULL;
148     }else {
149         ERR("GetValue failed: %08x\n", nsres);
150         hres = E_FAIL;
151     }
152
153     nsAString_Finish(&value_str);
154     return hres;
155 }
156
157 static HRESULT WINAPI HTMLTextAreaElement_put_name(IHTMLTextAreaElement *iface, BSTR v)
158 {
159     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
160     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
161     return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI HTMLTextAreaElement_get_name(IHTMLTextAreaElement *iface, BSTR *p)
165 {
166     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
167     nsAString name_str;
168     const PRUnichar *name;
169     nsresult nsres;
170
171     TRACE("(%p)->(%p)\n", This, p);
172
173     nsAString_Init(&name_str, NULL);
174
175     nsres = nsIDOMHTMLTextAreaElement_GetName(This->nstextarea, &name_str);
176     if(NS_SUCCEEDED(nsres)) {
177         nsAString_GetData(&name_str, &name);
178         *p = SysAllocString(name);
179     }else {
180         ERR("GetName failed: %08x\n", nsres);
181     }
182
183     nsAString_Finish(&name_str);
184
185     TRACE("%s\n", debugstr_w(*p));
186     return S_OK;
187 }
188
189 static HRESULT WINAPI HTMLTextAreaElement_put_status(IHTMLTextAreaElement *iface, VARIANT v)
190 {
191     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
192     FIXME("(%p)->()\n", This);
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI HTMLTextAreaElement_get_status(IHTMLTextAreaElement *iface, VARIANT *p)
197 {
198     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
199     FIXME("(%p)->(%p)\n", This, p);
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI HTMLTextAreaElement_put_disabled(IHTMLTextAreaElement *iface, VARIANT_BOOL v)
204 {
205     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
206     FIXME("(%p)->(%x)\n", This, v);
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI HTMLTextAreaElement_get_disabled(IHTMLTextAreaElement *iface, VARIANT_BOOL *p)
211 {
212     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
213     FIXME("(%p)->(%p)\n", This, p);
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI HTMLTextAreaElement_get_form(IHTMLTextAreaElement *iface, IHTMLFormElement **p)
218 {
219     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
220     FIXME("(%p)->(%p)\n", This, p);
221     return E_NOTIMPL;
222 }
223
224 static HRESULT WINAPI HTMLTextAreaElement_put_defaultValue(IHTMLTextAreaElement *iface, BSTR v)
225 {
226     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
227     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI HTMLTextAreaElement_get_defaultValue(IHTMLTextAreaElement *iface, BSTR *p)
232 {
233     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
234     FIXME("(%p)->(%p)\n", This, p);
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI HTMLTextAreaElement_select(IHTMLTextAreaElement *iface)
239 {
240     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
241     FIXME("(%p)\n", This);
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI HTMLTextAreaElement_put_onchange(IHTMLTextAreaElement *iface, VARIANT v)
246 {
247     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
248     FIXME("(%p)->()\n", This);
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI HTMLTextAreaElement_get_onchange(IHTMLTextAreaElement *iface, VARIANT *p)
253 {
254     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
255     FIXME("(%p)->(%p)\n", This, p);
256     return E_NOTIMPL;
257 }
258
259 static HRESULT WINAPI HTMLTextAreaElement_put_onselect(IHTMLTextAreaElement *iface, VARIANT v)
260 {
261     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
262     FIXME("(%p)->()\n", This);
263     return E_NOTIMPL;
264 }
265
266 static HRESULT WINAPI HTMLTextAreaElement_get_onselect(IHTMLTextAreaElement *iface, VARIANT *p)
267 {
268     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
269     FIXME("(%p)->(%p)\n", This, p);
270     return E_NOTIMPL;
271 }
272
273 static HRESULT WINAPI HTMLTextAreaElement_put_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL v)
274 {
275     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
276     nsresult nsres;
277
278     TRACE("(%p)->(%x)\n", This, v);
279
280     nsres = nsIDOMHTMLTextAreaElement_SetReadOnly(This->nstextarea, v != VARIANT_FALSE);
281     if(NS_FAILED(nsres)) {
282         ERR("SetReadOnly failed: %08x\n", nsres);
283         return E_FAIL;
284     }
285
286     return S_OK;
287 }
288
289 static HRESULT WINAPI HTMLTextAreaElement_get_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL *p)
290 {
291     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
292     PRBool b;
293     nsresult nsres;
294
295     TRACE("(%p)->(%p)\n", This, p);
296
297     nsres = nsIDOMHTMLTextAreaElement_GetReadOnly(This->nstextarea, &b);
298     if(NS_FAILED(nsres)) {
299         ERR("GetReadOnly failed: %08x\n", nsres);
300         return E_FAIL;
301     }
302
303     *p = b ? VARIANT_TRUE : VARIANT_FALSE;
304     return S_OK;
305 }
306
307 static HRESULT WINAPI HTMLTextAreaElement_put_rows(IHTMLTextAreaElement *iface, LONG v)
308 {
309     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
310     FIXME("(%p)->(%d)\n", This, v);
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI HTMLTextAreaElement_get_rows(IHTMLTextAreaElement *iface, LONG *p)
315 {
316     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
317     FIXME("(%p)->(%p)\n", This, p);
318     return E_NOTIMPL;
319 }
320
321 static HRESULT WINAPI HTMLTextAreaElement_put_cols(IHTMLTextAreaElement *iface, LONG v)
322 {
323     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
324     FIXME("(%p)->(%d)\n", This, v);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI HTMLTextAreaElement_get_cols(IHTMLTextAreaElement *iface, LONG *p)
329 {
330     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
331     FIXME("(%p)->(%p)\n", This, p);
332     return E_NOTIMPL;
333 }
334
335 static HRESULT WINAPI HTMLTextAreaElement_put_wrap(IHTMLTextAreaElement *iface, BSTR v)
336 {
337     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
338     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI HTMLTextAreaElement_get_wrap(IHTMLTextAreaElement *iface, BSTR *p)
343 {
344     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
345     FIXME("(%p)->(%p)\n", This, p);
346     return E_NOTIMPL;
347 }
348
349 static HRESULT WINAPI HTMLTextAreaElement_createTextRange(IHTMLTextAreaElement *iface,
350                                                           IHTMLTxtRange **range)
351 {
352     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
353     FIXME("(%p)->(%p)\n", This, range);
354     return E_NOTIMPL;
355 }
356
357 static const IHTMLTextAreaElementVtbl HTMLTextAreaElementVtbl = {
358     HTMLTextAreaElement_QueryInterface,
359     HTMLTextAreaElement_AddRef,
360     HTMLTextAreaElement_Release,
361     HTMLTextAreaElement_GetTypeInfoCount,
362     HTMLTextAreaElement_GetTypeInfo,
363     HTMLTextAreaElement_GetIDsOfNames,
364     HTMLTextAreaElement_Invoke,
365     HTMLTextAreaElement_get_type,
366     HTMLTextAreaElement_put_value,
367     HTMLTextAreaElement_get_value,
368     HTMLTextAreaElement_put_name,
369     HTMLTextAreaElement_get_name,
370     HTMLTextAreaElement_put_status,
371     HTMLTextAreaElement_get_status,
372     HTMLTextAreaElement_put_disabled,
373     HTMLTextAreaElement_get_disabled,
374     HTMLTextAreaElement_get_form,
375     HTMLTextAreaElement_put_defaultValue,
376     HTMLTextAreaElement_get_defaultValue,
377     HTMLTextAreaElement_select,
378     HTMLTextAreaElement_put_onchange,
379     HTMLTextAreaElement_get_onchange,
380     HTMLTextAreaElement_put_onselect,
381     HTMLTextAreaElement_get_onselect,
382     HTMLTextAreaElement_put_readOnly,
383     HTMLTextAreaElement_get_readOnly,
384     HTMLTextAreaElement_put_rows,
385     HTMLTextAreaElement_get_rows,
386     HTMLTextAreaElement_put_cols,
387     HTMLTextAreaElement_get_cols,
388     HTMLTextAreaElement_put_wrap,
389     HTMLTextAreaElement_get_wrap,
390     HTMLTextAreaElement_createTextRange
391 };
392
393 static inline HTMLTextAreaElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
394 {
395     return CONTAINING_RECORD(iface, HTMLTextAreaElement, element.node);
396 }
397
398 static HRESULT HTMLTextAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
399 {
400     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
401
402     *ppv = NULL;
403
404     if(IsEqualGUID(&IID_IUnknown, riid)) {
405         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
406         *ppv = &This->IHTMLTextAreaElement_iface;
407     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
408         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
409         *ppv = &This->IHTMLTextAreaElement_iface;
410     }else if(IsEqualGUID(&IID_IHTMLTextAreaElement, riid)) {
411         TRACE("(%p)->(IID_IHTMLTextAreaElement %p)\n", This, ppv);
412         *ppv = &This->IHTMLTextAreaElement_iface;
413     }
414
415     if(*ppv) {
416         IUnknown_AddRef((IUnknown*)*ppv);
417         return S_OK;
418     }
419
420     return HTMLElement_QI(&This->element.node, riid, ppv);
421 }
422
423 static void HTMLTextAreaElement_destructor(HTMLDOMNode *iface)
424 {
425     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
426
427     nsIDOMHTMLTextAreaElement_Release(This->nstextarea);
428
429     HTMLElement_destructor(&This->element.node);
430 }
431
432 static HRESULT HTMLTextAreaElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v)
433 {
434     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
435     return IHTMLTextAreaElement_put_disabled(&This->IHTMLTextAreaElement_iface, v);
436 }
437
438 static HRESULT HTMLTextAreaElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BOOL *p)
439 {
440     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
441     return IHTMLTextAreaElement_get_disabled(&This->IHTMLTextAreaElement_iface, p);
442 }
443
444 static const NodeImplVtbl HTMLTextAreaElementImplVtbl = {
445     HTMLTextAreaElement_QI,
446     HTMLTextAreaElement_destructor,
447     HTMLElement_clone,
448     NULL,
449     NULL,
450     HTMLTextAreaElementImpl_put_disabled,
451     HTMLTextAreaElementImpl_get_disabled
452 };
453
454 static const tid_t HTMLTextAreaElement_iface_tids[] = {
455     HTMLELEMENT_TIDS,
456     IHTMLTextAreaElement_tid,
457     0
458 };
459
460 static dispex_static_data_t HTMLTextAreaElement_dispex = {
461     NULL,
462     DispHTMLTextAreaElement_tid,
463     NULL,
464     HTMLTextAreaElement_iface_tids
465 };
466
467 HRESULT HTMLTextAreaElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
468 {
469     HTMLTextAreaElement *ret;
470     nsresult nsres;
471
472     ret = heap_alloc_zero(sizeof(HTMLTextAreaElement));
473     if(!ret)
474         return E_OUTOFMEMORY;
475
476     ret->IHTMLTextAreaElement_iface.lpVtbl = &HTMLTextAreaElementVtbl;
477     ret->element.node.vtbl = &HTMLTextAreaElementImplVtbl;
478
479     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLTextAreaElement,
480                                              (void**)&ret->nstextarea);
481     if(NS_FAILED(nsres)) {
482         ERR("Could not get nsDOMHTMLInputElement: %08x\n", nsres);
483         heap_free(ret);
484         return E_FAIL;
485     }
486
487     HTMLElement_Init(&ret->element, doc, nselem, &HTMLTextAreaElement_dispex);
488
489     *elem = &ret->element;
490     return S_OK;
491 }