mshtml: Added new get_handler_vector helper for creating handle_vector_t.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
72ee409e7f
commit
db67232ce2
|
@ -911,6 +911,27 @@ static inline event_target_t *get_event_target_data(EventTarget *event_target, B
|
||||||
return event_target->ptr = heap_alloc_zero(sizeof(event_target_t));
|
return event_target->ptr = heap_alloc_zero(sizeof(event_target_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static handler_vector_t *get_handler_vector(EventTarget *event_target, eventid_t eid, BOOL alloc)
|
||||||
|
{
|
||||||
|
event_target_t *data;
|
||||||
|
|
||||||
|
data = get_event_target_data(event_target, alloc);
|
||||||
|
if(!data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(alloc && !data->event_table[eid]) {
|
||||||
|
data->event_table[eid] = heap_alloc_zero(sizeof(*data->event_table[eid]));
|
||||||
|
if(data->event_table[eid]) {
|
||||||
|
const dispex_static_data_vtbl_t *vtbl = dispex_get_vtbl(&event_target->dispex);
|
||||||
|
if(vtbl->bind_event)
|
||||||
|
vtbl->bind_event(&event_target->dispex, eid);
|
||||||
|
else
|
||||||
|
FIXME("Unsupported event binding on target %p\n", event_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data->event_table[eid];
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT call_disp_func(IDispatch *disp, DISPPARAMS *dp, VARIANT *retv)
|
static HRESULT call_disp_func(IDispatch *disp, DISPPARAMS *dp, VARIANT *retv)
|
||||||
{
|
{
|
||||||
IDispatchEx *dispex;
|
IDispatchEx *dispex;
|
||||||
|
@ -1315,15 +1336,6 @@ HRESULT call_fire_event(HTMLDOMNode *node, eventid_t eid)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid)
|
|
||||||
{
|
|
||||||
if(event_target->event_table[eid])
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
event_target->event_table[eid] = heap_alloc_zero(sizeof(*event_target->event_table[eid]));
|
|
||||||
return event_target->event_table[eid] != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ensure_doc_nsevent_handler(HTMLDocumentNode *doc, eventid_t eid)
|
HRESULT ensure_doc_nsevent_handler(HTMLDocumentNode *doc, eventid_t eid)
|
||||||
{
|
{
|
||||||
nsIDOMNode *nsnode = NULL;
|
nsIDOMNode *nsnode = NULL;
|
||||||
|
@ -1378,16 +1390,6 @@ void detach_events(HTMLDocumentNode *doc)
|
||||||
release_nsevents(doc);
|
release_nsevents(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Caller should ensure that it's called only once for given event in the target. */
|
|
||||||
static void bind_event(EventTarget *event_target, eventid_t eid)
|
|
||||||
{
|
|
||||||
const dispex_static_data_vtbl_t *vtbl = dispex_get_vtbl(&event_target->dispex);
|
|
||||||
if(vtbl->bind_event)
|
|
||||||
vtbl->bind_event(&event_target->dispex, eid);
|
|
||||||
else
|
|
||||||
FIXME("Unsupported event binding on target %p\n", event_target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_event_handler(EventTarget *event_target, eventid_t eid)
|
static void remove_event_handler(EventTarget *event_target, eventid_t eid)
|
||||||
{
|
{
|
||||||
event_target_t *data;
|
event_target_t *data;
|
||||||
|
@ -1407,7 +1409,7 @@ static void remove_event_handler(EventTarget *event_target, eventid_t eid)
|
||||||
|
|
||||||
static HRESULT set_event_handler_disp(EventTarget *event_target, eventid_t eid, IDispatch *disp)
|
static HRESULT set_event_handler_disp(EventTarget *event_target, eventid_t eid, IDispatch *disp)
|
||||||
{
|
{
|
||||||
event_target_t *data;
|
handler_vector_t *handler_vector;
|
||||||
|
|
||||||
if(event_info[eid].flags & EVENT_FIXME)
|
if(event_info[eid].flags & EVENT_FIXME)
|
||||||
FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
|
FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
|
||||||
|
@ -1416,20 +1418,14 @@ static HRESULT set_event_handler_disp(EventTarget *event_target, eventid_t eid,
|
||||||
if(!disp)
|
if(!disp)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
data = get_event_target_data(event_target, TRUE);
|
handler_vector = get_handler_vector(event_target, eid, TRUE);
|
||||||
if(!data)
|
if(!handler_vector)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(!data->event_table[eid]) {
|
if(handler_vector->handler_prop)
|
||||||
if(!alloc_handler_vector(data, eid))
|
IDispatch_Release(handler_vector->handler_prop);
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
bind_event(event_target, eid);
|
handler_vector->handler_prop = disp;
|
||||||
}else if(data->event_table[eid]->handler_prop) {
|
|
||||||
IDispatch_Release(data->event_table[eid]->handler_prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
data->event_table[eid]->handler_prop = disp;
|
|
||||||
IDispatch_AddRef(disp);
|
IDispatch_AddRef(disp);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1503,7 +1499,7 @@ HRESULT get_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var
|
||||||
|
|
||||||
HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARIANT_BOOL *res)
|
HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARIANT_BOOL *res)
|
||||||
{
|
{
|
||||||
event_target_t *data;
|
handler_vector_t *handler_vector;
|
||||||
eventid_t eid;
|
eventid_t eid;
|
||||||
DWORD i = 0;
|
DWORD i = 0;
|
||||||
|
|
||||||
|
@ -1517,31 +1513,25 @@ HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARI
|
||||||
if(event_info[eid].flags & EVENT_FIXME)
|
if(event_info[eid].flags & EVENT_FIXME)
|
||||||
FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
|
FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
|
||||||
|
|
||||||
data = get_event_target_data(event_target, TRUE);
|
handler_vector = get_handler_vector(event_target, eid, TRUE);
|
||||||
if(!data)
|
if(!handler_vector)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(data->event_table[eid]) {
|
while(i < handler_vector->handler_cnt && handler_vector->handlers[i])
|
||||||
while(i < data->event_table[eid]->handler_cnt && data->event_table[eid]->handlers[i])
|
i++;
|
||||||
i++;
|
if(i == handler_vector->handler_cnt) {
|
||||||
}else if(alloc_handler_vector(data, eid)) {
|
|
||||||
bind_event(event_target, eid);
|
|
||||||
}else {
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
if(i == data->event_table[eid]->handler_cnt) {
|
|
||||||
if(i)
|
if(i)
|
||||||
data->event_table[eid]->handlers = heap_realloc_zero(data->event_table[eid]->handlers,
|
handler_vector->handlers = heap_realloc_zero(handler_vector->handlers,
|
||||||
(i + 1) * sizeof(*data->event_table[eid]->handlers));
|
(i + 1) * sizeof(*handler_vector->handlers));
|
||||||
else
|
else
|
||||||
data->event_table[eid]->handlers = heap_alloc_zero(sizeof(*data->event_table[eid]->handlers));
|
handler_vector->handlers = heap_alloc_zero(sizeof(*handler_vector->handlers));
|
||||||
if(!data->event_table[eid]->handlers)
|
if(!handler_vector->handlers)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
data->event_table[eid]->handler_cnt++;
|
handler_vector->handler_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDispatch_AddRef(disp);
|
IDispatch_AddRef(disp);
|
||||||
data->event_table[eid]->handlers[i] = disp;
|
handler_vector->handlers[i] = disp;
|
||||||
|
|
||||||
*res = VARIANT_TRUE;
|
*res = VARIANT_TRUE;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
Loading…
Reference in New Issue