From 38b6665ae6e2b2e194aec0a84167d025ccd85f45 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sun, 24 Sep 2006 23:12:06 +0200 Subject: [PATCH] mshtml: Add SETDOWNLOADSTATE task implementation and use it in IPersistMoniker::Load. --- dlls/mshtml/htmldoc.c | 2 + dlls/mshtml/mshtml_private.h | 15 +++++ dlls/mshtml/persist.c | 9 +++ dlls/mshtml/task.c | 110 +++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 066e87d0509..52c2c20c08c 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -143,6 +143,8 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface) TRACE("(%p) ref = %lu\n", This, ref); if(!ref) { + remove_doc_tasks(This); + if(This->client) IOleObject_SetClientSite(OLEOBJ(This), NULL); if(This->in_place_active) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 75d132c9cea..6cb6ce4c87f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -340,12 +340,27 @@ void install_wine_gecko(void); extern DWORD mshtml_tls; +typedef struct task_t { + HTMLDocument *doc; + + enum { + TASK_SETDOWNLOADSTATE, + TASK_PARSECOMPLETE + } task_id; + + struct task_t *next; +} task_t; + typedef struct { HWND thread_hwnd; + task_t *task_queue_head; + task_t *task_queue_tail; } thread_data_t; thread_data_t *get_thread_data(BOOL); HWND get_thread_hwnd(void); +void push_task(task_t*); +void remove_doc_tasks(HTMLDocument*); DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_JSProtocol, 0x3050F3B2, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 15af135424c..c9baf7c8a63 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -156,6 +156,7 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva HTMLDocument *This = PERSISTMON_THIS(iface); BSCallback *bscallback; LPOLESTR url = NULL; + task_t *task; HRESULT hres; nsresult nsres; @@ -219,6 +220,14 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva bscallback = create_bscallback(This, pimkName); + task = mshtml_alloc(sizeof(task_t)); + + task->doc = This; + task->task_id = TASK_SETDOWNLOADSTATE; + task->next = NULL; + + push_task(task); + if(This->nscontainer) { nsIInputStream *post_data_stream = get_post_data_stream(pibc); diff --git a/dlls/mshtml/task.c b/dlls/mshtml/task.c index 0619cd1be46..6af1cda01c8 100644 --- a/dlls/mshtml/task.c +++ b/dlls/mshtml/task.c @@ -37,8 +37,118 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define WM_PROCESSTASK 0x8008 +void push_task(task_t *task) +{ + thread_data_t *thread_data = get_thread_data(TRUE); + + if(thread_data->task_queue_tail) + thread_data->task_queue_tail->next = task; + else + thread_data->task_queue_head = task; + + thread_data->task_queue_tail = task; + + PostMessageW(thread_data->thread_hwnd, WM_PROCESSTASK, 0, 0); +} + +static task_t *pop_task(void) +{ + thread_data_t *thread_data = get_thread_data(TRUE); + task_t *task = thread_data->task_queue_head; + + if(!task) + return NULL; + + thread_data->task_queue_head = task->next; + if(!thread_data->task_queue_head) + thread_data->task_queue_tail = NULL; + + return task; +} + +void remove_doc_tasks(HTMLDocument *doc) +{ + thread_data_t *thread_data = get_thread_data(FALSE); + task_t *iter, *tmp; + + while(thread_data->task_queue_head + && thread_data->task_queue_head->doc == doc) + pop_task(); + + for(iter = thread_data->task_queue_head; iter; iter = iter->next) { + while(iter->next && iter->next->doc == doc) { + tmp = iter->next; + iter->next = tmp->next; + mshtml_free(tmp); + } + + if(!iter->next) + thread_data->task_queue_tail = iter; + } +} + +static void set_downloading(HTMLDocument *doc) +{ + IOleCommandTarget *olecmd; + HRESULT hres; + + TRACE("(%p)\n", doc); + + if(doc->frame) + IOleInPlaceFrame_SetStatusText(doc->frame, NULL /* FIXME */); + + if(!doc->client) + return; + + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(SUCCEEDED(hres)) { + VARIANT var; + + V_VT(&var) = VT_I4; + V_I4(&var) = 1; + + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, + &var, NULL); + IOleCommandTarget_Release(olecmd); + } + + if(doc->hostui) { + IDropTarget *drop_target = NULL; + + hres = IDocHostUIHandler_GetDropTarget(doc->hostui, NULL /* FIXME */, &drop_target); + if(drop_target) { + FIXME("Use IDropTarget\n"); + IDropTarget_Release(drop_target); + } + } +} + +static void process_task(task_t *task) +{ + switch(task->task_id) { + case TASK_SETDOWNLOADSTATE: + return set_downloading(task->doc); + default: + ERR("Wrong task_id %d\n", task->task_id); + } +} + static LRESULT WINAPI hidden_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + switch(msg) { + case WM_PROCESSTASK: + while(1) { + task_t *task = pop_task(); + if(!task) + break; + + process_task(task); + mshtml_free(task); + } + + return 0; + } + if(msg > WM_USER) FIXME("(%p %d %x %lx)\n", hwnd, msg, wParam, lParam);