Sync to trunk (r44371)
[reactos.git] / reactos / dll / win32 / mshtml / task.c
index 93edd65..c5182f7 100644 (file)
@@ -27,8 +27,6 @@
 #include "winbase.h"
 #include "winuser.h"
 #include "ole2.h"
-#include "mshtmcid.h"
-#include "shlguid.h"
 
 #include "wine/debug.h"
 
@@ -49,10 +47,14 @@ typedef struct {
     struct list entry;
 } task_timer_t;
 
-void push_task(task_t *task)
+void push_task(task_t *task, task_proc_t proc, LONG magic)
 {
     thread_data_t *thread_data = get_thread_data(TRUE);
 
+    task->target_magic = magic;
+    task->proc = proc;
+    task->next = NULL;
+
     if(thread_data->task_queue_tail)
         thread_data->task_queue_tail->next = task;
     else
@@ -87,16 +89,19 @@ static void release_task_timer(HWND thread_hwnd, task_timer_t *timer)
     heap_free(timer);
 }
 
-void remove_doc_tasks(const HTMLDocument *doc)
+void remove_target_tasks(LONG target)
 {
     thread_data_t *thread_data = get_thread_data(FALSE);
     struct list *liter, *ltmp;
     task_timer_t *timer;
     task_t *iter, *tmp;
 
+    if(!thread_data)
+        return;
+
     LIST_FOR_EACH_SAFE(liter, ltmp, &thread_data->timer_list) {
         timer = LIST_ENTRY(liter, task_timer_t, entry);
-        if(timer->doc == doc)
+        if(timer->doc->task_magic == target)
             release_task_timer(thread_data->thread_hwnd, timer);
     }
 
@@ -105,15 +110,12 @@ void remove_doc_tasks(const HTMLDocument *doc)
         SetTimer(thread_data->thread_hwnd, TIMER_ID, timer->time - GetTickCount(), NULL);
     }
 
-    if(!thread_data)
-        return;
-
     while(thread_data->task_queue_head
-          && thread_data->task_queue_head->doc == doc)
+          && thread_data->task_queue_head->target_magic == target)
         pop_task();
 
     for(iter = thread_data->task_queue_head; iter; iter = iter->next) {
-        while(iter->next && iter->next->doc == doc) {
+        while(iter->next && iter->next->target_magic == target) {
             tmp = iter->next;
             iter->next = tmp->next;
             heap_free(tmp);
@@ -124,6 +126,12 @@ void remove_doc_tasks(const HTMLDocument *doc)
     }
 }
 
+LONG get_task_target_magic(void)
+{
+    static LONG magic = 0x10000000;
+    return InterlockedIncrement(&magic);
+}
+
 static BOOL queue_timer(thread_data_t *thread_data, task_timer_t *timer)
 {
     task_timer_t *iter;
@@ -191,176 +199,30 @@ HRESULT clear_task_timer(HTMLDocument *doc, BOOL interval, DWORD id)
     return S_OK;
 }
 
-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);
-        }
-    }
-}
-
-/* Calls undocumented 69 cmd of CGID_Explorer */
-static void call_explorer_69(HTMLDocument *doc)
-{
-    IOleCommandTarget *olecmd;
-    VARIANT var;
-    HRESULT hres;
-
-    if(!doc->client)
-        return;
-
-    hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
-    if(FAILED(hres))
-        return;
-
-    VariantInit(&var);
-    hres = IOleCommandTarget_Exec(olecmd, &CGID_Explorer, 69, 0, NULL, &var);
-    IOleCommandTarget_Release(olecmd);
-    if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL)
-        FIXME("handle result\n");
-}
-
-static void set_parsecomplete(HTMLDocument *doc)
+void parse_complete(HTMLDocumentObj *doc)
 {
-    IOleCommandTarget *olecmd = NULL;
-
     TRACE("(%p)\n", doc);
 
-    if(doc->usermode == EDITMODE)
-        init_editor(doc);
-
-    call_explorer_69(doc);
-    call_property_onchanged(&doc->cp_propnotif, 1005);
-    call_explorer_69(doc);
-
-    doc->readystate = READYSTATE_INTERACTIVE;
-    call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE);
-
-    if(doc->client)
-        IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
-
-    if(olecmd) {
-        VARIANT state, progress;
-
-        V_VT(&progress) = VT_I4;
-        V_I4(&progress) = 0;
-        IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER,
-                               &progress, NULL);
-
-        V_VT(&state) = VT_I4;
-        V_I4(&state) = 0;
-        IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER,
-                               &state, NULL);
-
-        IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL);
-        IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL);
-        IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL);
-
-        IOleCommandTarget_Release(olecmd);
-    }
-
-    doc->readystate = READYSTATE_COMPLETE;
-    call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE);
-
-    if(doc->frame) {
-        static const WCHAR wszDone[] = {'D','o','n','e',0};
-        IOleInPlaceFrame_SetStatusText(doc->frame, wszDone);
     }
 
-    update_title(doc);
-}
-
-static void set_progress(HTMLDocument *doc)
+static void call_timer_disp(IDispatch *disp)
 {
-    IOleCommandTarget *olecmd = NULL;
+    DISPPARAMS dp = {NULL, NULL, 0, 0};
+    EXCEPINFO ei;
+    VARIANT res;
     HRESULT hres;
 
-    TRACE("(%p)\n", doc);
-
-    if(doc->client)
-        IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
-
-    if(olecmd) {
-        VARIANT progress_max, progress;
-
-        V_VT(&progress_max) = VT_I4;
-        V_I4(&progress_max) = 0; /* FIXME */
-        IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSMAX, OLECMDEXECOPT_DONTPROMPTUSER,
-                               &progress_max, NULL);
-
-        V_VT(&progress) = VT_I4;
-        V_I4(&progress) = 0; /* FIXME */
-        IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER,
-                               &progress, NULL);
-    }
+    V_VT(&res) = VT_EMPTY;
+    memset(&ei, 0, sizeof(ei));
 
-    if(doc->usermode == EDITMODE && doc->hostui) {
-        DOCHOSTUIINFO hostinfo;
-
-        memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
-        hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
-        hres = IDocHostUIHandler_GetHostInfo(doc->hostui, &hostinfo);
-        if(SUCCEEDED(hres))
-            /* FIXME: use hostinfo */
-            TRACE("hostinfo = {%u %08x %08x %s %s}\n",
-                    hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
-                    debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
-    }
-}
-
-static void task_start_binding(HTMLDocument *doc, BSCallback *bscallback)
-{
-    if(doc)
-        start_binding(doc, bscallback, NULL);
-    IUnknown_Release((IUnknown*)bscallback);
-}
+    TRACE(">>>\n");
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
+    if(hres == S_OK)
+        TRACE("<<<\n");
+    else
+        WARN("<<< %08x\n", hres);
 
-static void process_task(task_t *task)
-{
-    switch(task->task_id) {
-    case TASK_SETDOWNLOADSTATE:
-        set_downloading(task->doc);
-        break;
-    case TASK_PARSECOMPLETE:
-        set_parsecomplete(task->doc);
-        break;
-    case TASK_SETPROGRESS:
-        set_progress(task->doc);
-        break;
-    case TASK_START_BINDING:
-        task_start_binding(task->doc, (BSCallback*)task->bscallback);
-        break;
-    default:
-        ERR("Wrong task_id %d\n", task->task_id);
-    }
+    VariantClear(&res);
 }
 
 static LRESULT process_timer(void)
@@ -393,7 +255,7 @@ static LRESULT process_timer(void)
             release_task_timer(thread_data->thread_hwnd, timer);
         }
 
-        call_disp_func(doc, disp);
+        call_timer_disp(disp);
 
         IDispatch_Release(disp);
     }
@@ -411,7 +273,7 @@ static LRESULT WINAPI hidden_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
             if(!task)
                 break;
 
-            process_task(task);
+            task->proc(task);
             heap_free(task);
         }
 
@@ -462,11 +324,19 @@ thread_data_t *get_thread_data(BOOL create)
 {
     thread_data_t *thread_data;
 
-    if(!mshtml_tls) {
-        if(create)
-            mshtml_tls = TlsAlloc();
-        else
+    if(mshtml_tls == TLS_OUT_OF_INDEXES) {
+        DWORD tls;
+
+        if(!create)
+            return NULL;
+
+        tls = TlsAlloc();
+        if(tls == TLS_OUT_OF_INDEXES)
             return NULL;
+
+        tls = InterlockedCompareExchange((LONG*)&mshtml_tls, tls, TLS_OUT_OF_INDEXES);
+        if(tls != mshtml_tls)
+            TlsFree(tls);
     }
 
     thread_data = TlsGetValue(mshtml_tls);