- Sync msctf, mshtml and msxml3 with Wine 1.1.29

svn path=/trunk/; revision=42994
This commit is contained in:
Dmitry Chapyshev
2009-09-05 15:02:49 +00:00
parent fb3ef650c9
commit 4480f2ca35
47 changed files with 3096 additions and 757 deletions
+660
View File
@@ -0,0 +1,660 @@
/*
* ITfCompartmentMgr implementation
*
* Copyright 2009 Aric Stewart, 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 "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"
#include "oleauto.h"
#include "olectl.h"
#include "wine/unicode.h"
#include "wine/list.h"
#include "msctf.h"
#include "msctf_internal.h"
WINE_DEFAULT_DEBUG_CHANNEL(msctf);
typedef struct tagCompartmentValue {
struct list entry;
GUID guid;
TfClientId owner;
ITfCompartment *compartment;
} CompartmentValue;
typedef struct tagCompartmentMgr {
const ITfCompartmentMgrVtbl *CompartmentMgrVtbl;
LONG refCount;
IUnknown *pUnkOuter;
struct list values;
} CompartmentMgr;
typedef struct tagCompartmentEnumGuid {
const IEnumGUIDVtbl *Vtbl;
LONG refCount;
struct list *values;
struct list *cursor;
} CompartmentEnumGuid;
typedef struct tagCompartmentSink {
struct list entry;
union {
IUnknown *pIUnknown;
ITfCompartmentEventSink *pITfCompartmentEventSink;
} interfaces;
} CompartmentSink;
typedef struct tagCompartment {
const ITfCompartmentVtbl *Vtbl;
const ITfSourceVtbl *SourceVtbl;
LONG refCount;
/* Only VT_I4, VT_UNKNOWN and VT_BSTR data types are allowed */
VARIANT variant;
CompartmentValue *valueData;
struct list CompartmentEventSink;
} Compartment;
static HRESULT CompartmentEnumGuid_Constructor(struct list* values, IEnumGUID **ppOut);
static HRESULT Compartment_Constructor(CompartmentValue *value, ITfCompartment **ppOut);
static inline Compartment *impl_from_ITfSourceVtbl(ITfSource *iface)
{
return (Compartment *)((char *)iface - FIELD_OFFSET(Compartment,SourceVtbl));
}
HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
struct list *cursor, *cursor2;
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->values)
{
CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
list_remove(cursor);
ITfCompartment_Release(value->compartment);
HeapFree(GetProcessHeap(),0,value);
}
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/*****************************************************
* ITfCompartmentMgr functions
*****************************************************/
static HRESULT WINAPI CompartmentMgr_QueryInterface(ITfCompartmentMgr *iface, REFIID iid, LPVOID *ppvOut)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
if (This->pUnkOuter)
return IUnknown_QueryInterface(This->pUnkOuter, iid, *ppvOut);
else
{
*ppvOut = NULL;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartmentMgr))
{
*ppvOut = This;
}
if (*ppvOut)
{
IUnknown_AddRef(iface);
return S_OK;
}
WARN("unsupported interface: %s\n", debugstr_guid(iid));
return E_NOINTERFACE;
}
}
static ULONG WINAPI CompartmentMgr_AddRef(ITfCompartmentMgr *iface)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
if (This->pUnkOuter)
return IUnknown_AddRef(This->pUnkOuter);
else
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI CompartmentMgr_Release(ITfCompartmentMgr *iface)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
if (This->pUnkOuter)
return IUnknown_Release(This->pUnkOuter);
else
{
ULONG ret;
ret = InterlockedDecrement(&This->refCount);
if (ret == 0)
CompartmentMgr_Destructor(iface);
return ret;
}
}
static HRESULT WINAPI CompartmentMgr_GetCompartment(ITfCompartmentMgr *iface,
REFGUID rguid, ITfCompartment **ppcomp)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
CompartmentValue* value;
struct list *cursor;
HRESULT hr;
TRACE("(%p) %s %p\n",This,debugstr_guid(rguid),ppcomp);
LIST_FOR_EACH(cursor, &This->values)
{
value = LIST_ENTRY(cursor,CompartmentValue,entry);
if (IsEqualGUID(rguid,&value->guid))
{
ITfCompartment_AddRef(value->compartment);
*ppcomp = value->compartment;
return S_OK;
}
}
value = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentValue));
value->guid = *rguid;
value->owner = 0;
hr = Compartment_Constructor(value,&value->compartment);
if (SUCCEEDED(hr))
{
list_add_head(&This->values,&value->entry);
ITfCompartment_AddRef(value->compartment);
*ppcomp = value->compartment;
}
else
{
HeapFree(GetProcessHeap(),0,value);
*ppcomp = NULL;
}
return hr;
}
static HRESULT WINAPI CompartmentMgr_ClearCompartment(ITfCompartmentMgr *iface,
TfClientId tid, REFGUID rguid)
{
struct list *cursor;
CompartmentMgr *This = (CompartmentMgr *)iface;
TRACE("(%p) %i %s\n",This,tid,debugstr_guid(rguid));
LIST_FOR_EACH(cursor, &This->values)
{
CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
if (IsEqualGUID(rguid,&value->guid))
{
if (value->owner && tid != value->owner)
return E_UNEXPECTED;
list_remove(cursor);
ITfCompartment_Release(value->compartment);
HeapFree(GetProcessHeap(),0,value);
return S_OK;
}
}
return CONNECT_E_NOCONNECTION;
}
static HRESULT WINAPI CompartmentMgr_EnumCompartments(ITfCompartmentMgr *iface,
IEnumGUID **ppEnum)
{
CompartmentMgr *This = (CompartmentMgr *)iface;
TRACE("(%p) %p\n",This,ppEnum);
if (!ppEnum)
return E_INVALIDARG;
return CompartmentEnumGuid_Constructor(&This->values, ppEnum);
}
static const ITfCompartmentMgrVtbl CompartmentMgr_CompartmentMgrVtbl =
{
CompartmentMgr_QueryInterface,
CompartmentMgr_AddRef,
CompartmentMgr_Release,
CompartmentMgr_GetCompartment,
CompartmentMgr_ClearCompartment,
CompartmentMgr_EnumCompartments
};
HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
{
CompartmentMgr *This;
if (!ppOut)
return E_POINTER;
if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentMgr));
if (This == NULL)
return E_OUTOFMEMORY;
This->CompartmentMgrVtbl = &CompartmentMgr_CompartmentMgrVtbl;
This->pUnkOuter = pUnkOuter;
list_init(&This->values);
if (pUnkOuter)
{
TRACE("returning %p\n", This);
*ppOut = (IUnknown*)This;
return S_OK;
}
else
{
HRESULT hr;
hr = IUnknown_QueryInterface((IUnknown*)This, riid, (LPVOID*)ppOut);
if (FAILED(hr))
HeapFree(GetProcessHeap(),0,This);
return hr;
}
}
/**************************************************
* IEnumGUID implementaion for ITfCompartmentMgr::EnumCompartments
**************************************************/
static void CompartmentEnumGuid_Destructor(CompartmentEnumGuid *This)
{
TRACE("destroying %p\n", This);
HeapFree(GetProcessHeap(),0,This);
}
static HRESULT WINAPI CompartmentEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
*ppvOut = NULL;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
{
*ppvOut = This;
}
if (*ppvOut)
{
IUnknown_AddRef(iface);
return S_OK;
}
WARN("unsupported interface: %s\n", debugstr_guid(iid));
return E_NOINTERFACE;
}
static ULONG WINAPI CompartmentEnumGuid_AddRef(IEnumGUID *iface)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid*)iface;
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI CompartmentEnumGuid_Release(IEnumGUID *iface)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
ULONG ret;
ret = InterlockedDecrement(&This->refCount);
if (ret == 0)
CompartmentEnumGuid_Destructor(This);
return ret;
}
/*****************************************************
* IEnumGuid functions
*****************************************************/
static HRESULT WINAPI CompartmentEnumGuid_Next( LPENUMGUID iface,
ULONG celt, GUID *rgelt, ULONG *pceltFetched)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
ULONG fetched = 0;
TRACE("(%p)\n",This);
if (rgelt == NULL) return E_POINTER;
while (fetched < celt && This->cursor)
{
CompartmentValue* value = LIST_ENTRY(This->cursor,CompartmentValue,entry);
if (!value)
break;
This->cursor = list_next(This->values,This->cursor);
*rgelt = value->guid;
++fetched;
++rgelt;
}
if (pceltFetched) *pceltFetched = fetched;
return fetched == celt ? S_OK : S_FALSE;
}
static HRESULT WINAPI CompartmentEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
TRACE("(%p)\n",This);
This->cursor = list_next(This->values,This->cursor);
return S_OK;
}
static HRESULT WINAPI CompartmentEnumGuid_Reset( LPENUMGUID iface)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
TRACE("(%p)\n",This);
This->cursor = list_head(This->values);
return S_OK;
}
static HRESULT WINAPI CompartmentEnumGuid_Clone( LPENUMGUID iface,
IEnumGUID **ppenum)
{
CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
HRESULT res;
TRACE("(%p)\n",This);
if (ppenum == NULL) return E_POINTER;
res = CompartmentEnumGuid_Constructor(This->values, ppenum);
if (SUCCEEDED(res))
{
CompartmentEnumGuid *new_This = (CompartmentEnumGuid *)*ppenum;
new_This->cursor = This->cursor;
}
return res;
}
static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
CompartmentEnumGuid_QueryInterface,
CompartmentEnumGuid_AddRef,
CompartmentEnumGuid_Release,
CompartmentEnumGuid_Next,
CompartmentEnumGuid_Skip,
CompartmentEnumGuid_Reset,
CompartmentEnumGuid_Clone
};
static HRESULT CompartmentEnumGuid_Constructor(struct list *values, IEnumGUID **ppOut)
{
CompartmentEnumGuid *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentEnumGuid));
if (This == NULL)
return E_OUTOFMEMORY;
This->Vtbl= &IEnumGUID_Vtbl;
This->refCount = 1;
This->values = values;
This->cursor = list_head(values);
TRACE("returning %p\n", This);
*ppOut = (IEnumGUID*)This;
return S_OK;
}
/**************************************************
* ITfCompartment
**************************************************/
static void free_sink(CompartmentSink *sink)
{
IUnknown_Release(sink->interfaces.pIUnknown);
HeapFree(GetProcessHeap(),0,sink);
}
static void Compartment_Destructor(Compartment *This)
{
struct list *cursor, *cursor2;
TRACE("destroying %p\n", This);
VariantClear(&This->variant);
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CompartmentEventSink)
{
CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
list_remove(cursor);
free_sink(sink);
}
HeapFree(GetProcessHeap(),0,This);
}
static HRESULT WINAPI Compartment_QueryInterface(ITfCompartment *iface, REFIID iid, LPVOID *ppvOut)
{
Compartment *This = (Compartment *)iface;
*ppvOut = NULL;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartment))
{
*ppvOut = This;
}
else if (IsEqualIID(iid, &IID_ITfSource))
{
*ppvOut = &This->SourceVtbl;
}
if (*ppvOut)
{
IUnknown_AddRef(iface);
return S_OK;
}
WARN("unsupported interface: %s\n", debugstr_guid(iid));
return E_NOINTERFACE;
}
static ULONG WINAPI Compartment_AddRef(ITfCompartment *iface)
{
Compartment *This = (Compartment*)iface;
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI Compartment_Release(ITfCompartment *iface)
{
Compartment *This = (Compartment *)iface;
ULONG ret;
ret = InterlockedDecrement(&This->refCount);
if (ret == 0)
Compartment_Destructor(This);
return ret;
}
static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
TfClientId tid, const VARIANT *pvarValue)
{
Compartment *This = (Compartment *)iface;
struct list *cursor;
TRACE("(%p) %i %p\n",This,tid,pvarValue);
if (!pvarValue)
return E_INVALIDARG;
if (!(V_VT(pvarValue) == VT_BSTR || V_VT(pvarValue) == VT_I4 ||
V_VT(pvarValue) == VT_UNKNOWN))
return E_INVALIDARG;
if (!This->valueData->owner)
This->valueData->owner = tid;
VariantClear(&This->variant);
/* Shallow copy of value and type */
This->variant = *pvarValue;
if (V_VT(pvarValue) == VT_BSTR)
V_BSTR(&This->variant) = SysAllocStringByteLen((char*)V_BSTR(pvarValue),
SysStringByteLen(V_BSTR(pvarValue)));
else if (V_VT(pvarValue) == VT_UNKNOWN)
IUnknown_AddRef(V_UNKNOWN(&This->variant));
LIST_FOR_EACH(cursor, &This->CompartmentEventSink)
{
CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
ITfCompartmentEventSink_OnChange(sink->interfaces.pITfCompartmentEventSink,&This->valueData->guid);
}
return S_OK;
}
static HRESULT WINAPI Compartment_GetValue(ITfCompartment *iface,
VARIANT *pvarValue)
{
Compartment *This = (Compartment *)iface;
TRACE("(%p) %p\n",This, pvarValue);
if (!pvarValue)
return E_INVALIDARG;
VariantInit(pvarValue);
if (V_VT(&This->variant) == VT_EMPTY) return S_FALSE;
return VariantCopy(pvarValue,&This->variant);
}
static const ITfCompartmentVtbl ITfCompartment_Vtbl ={
Compartment_QueryInterface,
Compartment_AddRef,
Compartment_Release,
Compartment_SetValue,
Compartment_GetValue
};
/*****************************************************
* ITfSource functions
*****************************************************/
static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
{
Compartment *This = impl_from_ITfSourceVtbl(iface);
return Compartment_QueryInterface((ITfCompartment *)This, iid, *ppvOut);
}
static ULONG WINAPI Source_AddRef(ITfSource *iface)
{
Compartment *This = impl_from_ITfSourceVtbl(iface);
return Compartment_AddRef((ITfCompartment*)This);
}
static ULONG WINAPI Source_Release(ITfSource *iface)
{
Compartment *This = impl_from_ITfSourceVtbl(iface);
return Compartment_Release((ITfCompartment *)This);
}
static WINAPI HRESULT CompartmentSource_AdviseSink(ITfSource *iface,
REFIID riid, IUnknown *punk, DWORD *pdwCookie)
{
CompartmentSink *cs;
Compartment *This = impl_from_ITfSourceVtbl(iface);
TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
if (!riid || !punk || !pdwCookie)
return E_INVALIDARG;
if (IsEqualIID(riid, &IID_ITfCompartmentEventSink))
{
cs = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentSink));
if (!cs)
return E_OUTOFMEMORY;
if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&cs->interfaces.pITfCompartmentEventSink)))
{
HeapFree(GetProcessHeap(),0,cs);
return CONNECT_E_CANNOTCONNECT;
}
list_add_head(&This->CompartmentEventSink,&cs->entry);
*pdwCookie = generate_Cookie(COOKIE_MAGIC_COMPARTMENTSINK , cs);
}
else
{
FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
return E_NOTIMPL;
}
TRACE("cookie %x\n",*pdwCookie);
return S_OK;
}
static WINAPI HRESULT CompartmentSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
{
CompartmentSink *sink;
Compartment *This = impl_from_ITfSourceVtbl(iface);
TRACE("(%p) %x\n",This,pdwCookie);
if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_COMPARTMENTSINK)
return E_INVALIDARG;
sink = (CompartmentSink*)remove_Cookie(pdwCookie);
if (!sink)
return CONNECT_E_NOCONNECTION;
list_remove(&sink->entry);
free_sink(sink);
return S_OK;
}
static const ITfSourceVtbl Compartment_SourceVtbl =
{
Source_QueryInterface,
Source_AddRef,
Source_Release,
CompartmentSource_AdviseSink,
CompartmentSource_UnadviseSink,
};
static HRESULT Compartment_Constructor(CompartmentValue *valueData, ITfCompartment **ppOut)
{
Compartment *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Compartment));
if (This == NULL)
return E_OUTOFMEMORY;
This->Vtbl= &ITfCompartment_Vtbl;
This->SourceVtbl = &Compartment_SourceVtbl;
This->refCount = 1;
This->valueData = valueData;
VariantInit(&This->variant);
list_init(&This->CompartmentEventSink);
TRACE("returning %p\n", This);
*ppOut = (ITfCompartment*)This;
return S_OK;
}
+283 -20
View File
@@ -61,15 +61,20 @@ typedef struct tagContext {
/* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
/* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
/* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
/* const ITfInsertAtSelectionVtbl *InsertAtSelectionVtbl; */
const ITfInsertAtSelectionVtbl *InsertAtSelectionVtbl;
/* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
/* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
/* const ITfSourceSingleVtbl *SourceSingleVtbl; */
const ITfSourceSingleVtbl *SourceSingleVtbl;
LONG refCount;
BOOL connected;
/* Aggregation */
ITfCompartmentMgr *CompartmentMgr;
TfClientId tidOwner;
TfEditCookie defaultCookie;
TS_STATUS documentStatus;
ITfDocumentMgr *manager;
ITextStoreACP *pITextStoreACP;
ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
@@ -107,6 +112,16 @@ static inline Context *impl_from_ITfSourceVtbl(ITfSource *iface)
return (Context *)((char *)iface - FIELD_OFFSET(Context,SourceVtbl));
}
static inline Context *impl_from_ITfInsertAtSelectionVtbl(ITfInsertAtSelection*iface)
{
return (Context *)((char *)iface - FIELD_OFFSET(Context,InsertAtSelectionVtbl));
}
static inline Context *impl_from_ITfSourceSingleVtbl(ITfSourceSingle* iface)
{
return (Context *)((char *)iface - FIELD_OFFSET(Context,SourceSingleVtbl));
}
static void free_sink(ContextSink *sink)
{
IUnknown_Release(sink->interfaces.pIUnknown);
@@ -169,6 +184,7 @@ static void Context_Destructor(Context *This)
free_sink(sink);
}
CompartmentMgr_Destructor(This->CompartmentMgr);
HeapFree(GetProcessHeap(),0,This);
}
@@ -185,6 +201,18 @@ static HRESULT WINAPI Context_QueryInterface(ITfContext *iface, REFIID iid, LPVO
{
*ppvOut = &This->SourceVtbl;
}
else if (IsEqualIID(iid, &IID_ITfInsertAtSelection))
{
*ppvOut = &This->InsertAtSelectionVtbl;
}
else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
{
*ppvOut = This->CompartmentMgr;
}
else if (IsEqualIID(iid, &IID_ITfSourceSingle))
{
*ppvOut = &This->SourceSingleVtbl;
}
if (*ppvOut)
{
@@ -223,7 +251,6 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
HRESULT hr;
Context *This = (Context *)iface;
DWORD dwLockFlags = 0x0;
TS_STATUS status;
TRACE("(%p) %i %p %x %p\n",This, tid, pes, dwFlags, phrSession);
@@ -248,10 +275,10 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
else if (dwFlags & TF_ES_READ)
dwLockFlags |= TS_LF_READ;
/* TODO: cache this */
ITextStoreACP_GetStatus(This->pITextStoreACP, &status);
if (!This->documentStatus.dwDynamicFlags)
ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (status.dwDynamicFlags & TS_SD_READONLY))
if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (This->documentStatus.dwDynamicFlags & TS_SD_READONLY))
{
*phrSession = TS_E_READONLY;
return S_OK;
@@ -263,7 +290,6 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
return E_INVALIDARG;
}
hr = ITextStoreACP_RequestLock(This->pITextStoreACP, dwLockFlags, phrSession);
return hr;
@@ -341,9 +367,39 @@ static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
TfEditCookie ec, ULONG ulCount, const TF_SELECTION *pSelection)
{
TS_SELECTION_ACP *acp;
Context *This = (Context *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
INT i;
HRESULT hr;
TRACE("(%p) %i %i %p\n",This,ec,ulCount,pSelection);
if (!This->pITextStoreACP)
{
FIXME("Context does not have a ITextStoreACP\n");
return E_NOTIMPL;
}
if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
return TF_E_NOLOCK;
acp = HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP) * ulCount);
if (!acp)
return E_OUTOFMEMORY;
for (i = 0; i < ulCount; i++)
if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection[i], &acp[i])))
{
TRACE("Selection Conversion Failed\n");
HeapFree(GetProcessHeap(), 0 , acp);
return E_FAIL;
}
hr = ITextStoreACP_SetSelection(This->pITextStoreACP, ulCount, acp);
HeapFree(GetProcessHeap(), 0, acp);
return hr;
}
static HRESULT WINAPI Context_GetStart (ITfContext *iface,
@@ -419,8 +475,25 @@ static HRESULT WINAPI Context_GetStatus (ITfContext *iface,
TF_STATUS *pdcs)
{
Context *This = (Context *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %p\n",This,pdcs);
if (!This->connected)
return TF_E_DISCONNECTED;
if (!pdcs)
return E_INVALIDARG;
if (!This->pITextStoreACP)
{
FIXME("Context does not have a ITextStoreACP\n");
return E_NOTIMPL;
}
ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
*pdcs = This->documentStatus;
return S_OK;
}
static HRESULT WINAPI Context_GetProperty (ITfContext *iface,
@@ -460,8 +533,18 @@ static HRESULT WINAPI Context_GetDocumentMgr (ITfContext *iface,
ITfDocumentMgr **ppDm)
{
Context *This = (Context *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %p\n",This,ppDm);
if (!ppDm)
return E_INVALIDARG;
*ppDm = This->manager;
if (!This->manager)
return S_FALSE;
ITfDocumentMgr_AddRef(This->manager);
return S_OK;
}
static HRESULT WINAPI Context_CreateRangeBackup (ITfContext *iface,
@@ -579,7 +662,130 @@ static const ITfSourceVtbl Context_SourceVtbl =
ContextSource_UnadviseSink,
};
HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore)
/*****************************************************
* ITfInsertAtSelection functions
*****************************************************/
static HRESULT WINAPI InsertAtSelection_QueryInterface(ITfInsertAtSelection *iface, REFIID iid, LPVOID *ppvOut)
{
Context *This = impl_from_ITfInsertAtSelectionVtbl(iface);
return Context_QueryInterface((ITfContext *)This, iid, *ppvOut);
}
static ULONG WINAPI InsertAtSelection_AddRef(ITfInsertAtSelection *iface)
{
Context *This = impl_from_ITfInsertAtSelectionVtbl(iface);
return Context_AddRef((ITfContext *)This);
}
static ULONG WINAPI InsertAtSelection_Release(ITfInsertAtSelection *iface)
{
Context *This = impl_from_ITfInsertAtSelectionVtbl(iface);
return Context_Release((ITfContext *)This);
}
static WINAPI HRESULT InsertAtSelection_InsertTextAtSelection(
ITfInsertAtSelection *iface, TfEditCookie ec, DWORD dwFlags,
const WCHAR *pchText, LONG cch, ITfRange **ppRange)
{
Context *This = impl_from_ITfInsertAtSelectionVtbl(iface);
EditCookie *cookie;
LONG acpStart, acpEnd;
TS_TEXTCHANGE change;
HRESULT hr;
TRACE("(%p) %i %x %s %p\n",This, ec, dwFlags, debugstr_wn(pchText,cch), ppRange);
if (!This->connected)
return TF_E_DISCONNECTED;
if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
return TF_E_NOLOCK;
cookie = get_Cookie_data(ec);
if ((cookie->lockType & TS_LF_READWRITE) != TS_LF_READWRITE )
return TS_E_READONLY;
if (!This->pITextStoreACP)
{
FIXME("Context does not have a ITextStoreACP\n");
return E_NOTIMPL;
}
hr = ITextStoreACP_InsertTextAtSelection(This->pITextStoreACP, dwFlags, pchText, cch, &acpStart, &acpEnd, &change);
if (SUCCEEDED(hr))
Range_Constructor((ITfContext*)This, This->pITextStoreACP, cookie->lockType, change.acpStart, change.acpNewEnd, ppRange);
return hr;
}
static WINAPI HRESULT InsertAtSelection_InsertEmbeddedAtSelection(
ITfInsertAtSelection *iface, TfEditCookie ec, DWORD dwFlags,
IDataObject *pDataObject, ITfRange **ppRange)
{
Context *This = impl_from_ITfInsertAtSelectionVtbl(iface);
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
}
static const ITfInsertAtSelectionVtbl Context_InsertAtSelectionVtbl =
{
InsertAtSelection_QueryInterface,
InsertAtSelection_AddRef,
InsertAtSelection_Release,
InsertAtSelection_InsertTextAtSelection,
InsertAtSelection_InsertEmbeddedAtSelection,
};
/*****************************************************
* ITfSourceSingle functions
*****************************************************/
static HRESULT WINAPI SourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut)
{
Context *This = impl_from_ITfSourceSingleVtbl(iface);
return Context_QueryInterface((ITfContext *)This, iid, *ppvOut);
}
static ULONG WINAPI SourceSingle_AddRef(ITfSourceSingle *iface)
{
Context *This = impl_from_ITfSourceSingleVtbl(iface);
return Context_AddRef((ITfContext *)This);
}
static ULONG WINAPI SourceSingle_Release(ITfSourceSingle *iface)
{
Context *This = impl_from_ITfSourceSingleVtbl(iface);
return Context_Release((ITfContext *)This);
}
static WINAPI HRESULT SourceSingle_AdviseSingleSink( ITfSourceSingle *iface,
TfClientId tid, REFIID riid, IUnknown *punk)
{
Context *This = impl_from_ITfSourceSingleVtbl(iface);
FIXME("STUB:(%p) %i %s %p\n",This, tid, debugstr_guid(riid),punk);
return E_NOTIMPL;
}
static WINAPI HRESULT SourceSingle_UnadviseSingleSink( ITfSourceSingle *iface,
TfClientId tid, REFIID riid)
{
Context *This = impl_from_ITfSourceSingleVtbl(iface);
FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid));
return E_NOTIMPL;
}
static const ITfSourceSingleVtbl Context_SourceSingleVtbl =
{
SourceSingle_QueryInterface,
SourceSingle_AddRef,
SourceSingle_Release,
SourceSingle_AdviseSingleSink,
SourceSingle_UnadviseSingleSink,
};
HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
{
Context *This;
EditCookie *cookie;
@@ -599,9 +805,14 @@ HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **pp
This->ContextVtbl= &Context_ContextVtbl;
This->SourceVtbl = &Context_SourceVtbl;
This->InsertAtSelectionVtbl = &Context_InsertAtSelectionVtbl;
This->SourceSingleVtbl = &Context_SourceSingleVtbl;
This->refCount = 1;
This->tidOwner = tidOwner;
This->connected = FALSE;
This->manager = mgr;
CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
cookie->lockType = TF_ES_READ;
cookie->pOwningContext = This;
@@ -633,7 +844,7 @@ HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **pp
return S_OK;
}
HRESULT Context_Initialize(ITfContext *iface)
HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
{
Context *This = (Context *)iface;
@@ -644,6 +855,7 @@ HRESULT Context_Initialize(ITfContext *iface)
(IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
}
This->connected = TRUE;
This->manager = manager;
return S_OK;
}
@@ -658,6 +870,7 @@ HRESULT Context_Uninitialize(ITfContext *iface)
This->pITextStoreACPSink = NULL;
}
This->connected = FALSE;
This->manager = NULL;
return S_OK;
}
@@ -739,8 +952,28 @@ static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
DWORD dwFlags)
{
TextStoreACPSink *This = (TextStoreACPSink *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
HRESULT hr, hrSession;
TRACE("(%p) %x\n",This, dwFlags);
if (!This->pContext)
{
ERR("No context?\n");
return E_FAIL;
}
if (!This->pContext->pITextStoreACP)
{
FIXME("Context does not have a ITextStoreACP\n");
return E_NOTIMPL;
}
hr = ITextStoreACP_RequestLock(This->pContext->pITextStoreACP, TS_LF_READ, &hrSession);
if(SUCCEEDED(hr) && SUCCEEDED(hrSession))
This->pContext->documentStatus.dwDynamicFlags = dwFlags;
return S_OK;
}
static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
@@ -756,27 +989,57 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
{
TextStoreACPSink *This = (TextStoreACPSink *)iface;
HRESULT hr;
EditCookie *cookie;
EditCookie *cookie,*sinkcookie;
TfEditCookie ec;
struct list *cursor;
TRACE("(%p) %x\n",This, dwLockFlags);
if (!This->pContext || !This->pContext->currentEditSession)
if (!This->pContext)
{
ERR("OnLockGranted called on a context without a current edit session\n");
ERR("OnLockGranted called without a context\n");
return E_FAIL;
}
if (!This->pContext->currentEditSession)
{
FIXME("OnLockGranted called for something other than an EditSession\n");
return S_OK;
}
cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
if (!cookie)
return E_OUTOFMEMORY;
sinkcookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
if (!sinkcookie)
return E_OUTOFMEMORY;
cookie->lockType = dwLockFlags;
cookie->pOwningContext = This->pContext;
ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
hr = ITfEditSession_DoEditSession(This->pContext->currentEditSession, ec);
if ((dwLockFlags&TS_LF_READWRITE) == TS_LF_READWRITE)
{
TfEditCookie sc;
sinkcookie->lockType = TS_LF_READ;
sinkcookie->pOwningContext = This->pContext;
sc = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, sinkcookie);
/*TODO: implement ITfEditRecord */
LIST_FOR_EACH(cursor, &This->pContext->pTextEditSink)
{
ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
ITfTextEditSink_OnEndEdit(sink->interfaces.pITfTextEditSink,
(ITfContext*) &This->pContext, sc, NULL);
}
sinkcookie = remove_Cookie(sc);
}
HeapFree(GetProcessHeap(),0,sinkcookie);
ITfEditSession_Release(This->pContext->currentEditSession);
This->pContext->currentEditSession = NULL;
+168 -4
View File
@@ -45,10 +45,23 @@ typedef struct tagDocumentMgr {
const ITfSourceVtbl *SourceVtbl;
LONG refCount;
/* Aggregation */
ITfCompartmentMgr *CompartmentMgr;
ITfContext* contextStack[2]; /* limit of 2 contexts */
ITfThreadMgrEventSink* ThreadMgrSink;
} DocumentMgr;
typedef struct tagEnumTfContext {
const IEnumTfContextsVtbl *Vtbl;
LONG refCount;
DWORD index;
DocumentMgr *docmgr;
} EnumTfContext;
static HRESULT EnumTfContext_Constructor(DocumentMgr* mgr, IEnumTfContexts **ppOut);
static inline DocumentMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
{
return (DocumentMgr *)((char *)iface - FIELD_OFFSET(DocumentMgr,SourceVtbl));
@@ -56,11 +69,17 @@ static inline DocumentMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
static void DocumentMgr_Destructor(DocumentMgr *This)
{
ITfThreadMgr *tm;
TRACE("destroying %p\n", This);
TF_GetThreadMgr(&tm);
ThreadMgr_OnDocumentMgrDestruction(tm, (ITfDocumentMgr*)This);
if (This->contextStack[0])
ITfContext_Release(This->contextStack[0]);
if (This->contextStack[1])
ITfContext_Release(This->contextStack[1]);
CompartmentMgr_Destructor(This->CompartmentMgr);
HeapFree(GetProcessHeap(),0,This);
}
@@ -77,6 +96,10 @@ static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID i
{
*ppvOut = &This->SourceVtbl;
}
else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
{
*ppvOut = This->CompartmentMgr;
}
if (*ppvOut)
{
@@ -115,7 +138,7 @@ static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface,
{
DocumentMgr *This = (DocumentMgr *)iface;
TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
return Context_Constructor(tidOwner, punk, ppic, pecTextStore);
return Context_Constructor(tidOwner, punk, iface, ppic, pecTextStore);
}
static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
@@ -137,8 +160,8 @@ static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
This->contextStack[1] = This->contextStack[0];
This->contextStack[0] = check;
Context_Initialize(check, iface);
ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
Context_Initialize(check);
return S_OK;
}
@@ -225,8 +248,8 @@ static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **pp
static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
{
DocumentMgr *This = (DocumentMgr *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %p\n",This,ppEnum);
return EnumTfContext_Constructor(This, ppEnum);
}
static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
@@ -303,7 +326,148 @@ HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumen
This->refCount = 1;
This->ThreadMgrSink = ThreadMgrSink;
CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
TRACE("returning %p\n", This);
*ppOut = (ITfDocumentMgr*)This;
return S_OK;
}
/**************************************************
* IEnumTfContexts implementaion
**************************************************/
static void EnumTfContext_Destructor(EnumTfContext *This)
{
TRACE("destroying %p\n", This);
HeapFree(GetProcessHeap(),0,This);
}
static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFIID iid, LPVOID *ppvOut)
{
EnumTfContext *This = (EnumTfContext *)iface;
*ppvOut = NULL;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfContexts))
{
*ppvOut = This;
}
if (*ppvOut)
{
IUnknown_AddRef(iface);
return S_OK;
}
WARN("unsupported interface: %s\n", debugstr_guid(iid));
return E_NOINTERFACE;
}
static ULONG WINAPI EnumTfContext_AddRef(IEnumTfContexts *iface)
{
EnumTfContext *This = (EnumTfContext*)iface;
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
{
EnumTfContext *This = (EnumTfContext *)iface;
ULONG ret;
ret = InterlockedDecrement(&This->refCount);
if (ret == 0)
EnumTfContext_Destructor(This);
return ret;
}
static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface,
ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
{
EnumTfContext *This = (EnumTfContext *)iface;
ULONG fetched = 0;
TRACE("(%p)\n",This);
if (rgContext == NULL) return E_POINTER;
while (fetched < ulCount)
{
if (This->index > 1)
break;
if (!This->docmgr->contextStack[This->index])
break;
*rgContext = This->docmgr->contextStack[This->index];
ITfContext_AddRef(*rgContext);
++This->index;
++fetched;
++rgContext;
}
if (pcFetched) *pcFetched = fetched;
return fetched == ulCount ? S_OK : S_FALSE;
}
static HRESULT WINAPI EnumTfContext_Skip( IEnumTfContexts* iface, ULONG celt)
{
EnumTfContext *This = (EnumTfContext *)iface;
TRACE("(%p)\n",This);
This->index += celt;
return S_OK;
}
static HRESULT WINAPI EnumTfContext_Reset( IEnumTfContexts* iface)
{
EnumTfContext *This = (EnumTfContext *)iface;
TRACE("(%p)\n",This);
This->index = 0;
return S_OK;
}
static HRESULT WINAPI EnumTfContext_Clone( IEnumTfContexts *iface,
IEnumTfContexts **ppenum)
{
EnumTfContext *This = (EnumTfContext *)iface;
HRESULT res;
TRACE("(%p)\n",This);
if (ppenum == NULL) return E_POINTER;
res = EnumTfContext_Constructor(This->docmgr, ppenum);
if (SUCCEEDED(res))
{
EnumTfContext *new_This = (EnumTfContext *)*ppenum;
new_This->index = This->index;
}
return res;
}
static const IEnumTfContextsVtbl IEnumTfContexts_Vtbl ={
EnumTfContext_QueryInterface,
EnumTfContext_AddRef,
EnumTfContext_Release,
EnumTfContext_Clone,
EnumTfContext_Next,
EnumTfContext_Reset,
EnumTfContext_Skip
};
static HRESULT EnumTfContext_Constructor(DocumentMgr *mgr, IEnumTfContexts **ppOut)
{
EnumTfContext *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfContext));
if (This == NULL)
return E_OUTOFMEMORY;
This->Vtbl= &IEnumTfContexts_Vtbl;
This->refCount = 1;
This->docmgr = mgr;
TRACE("returning %p\n", This);
*ppOut = (IEnumTfContexts*)This;
return S_OK;
}
+108 -13
View File
@@ -43,10 +43,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(msctf);
static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
static const WCHAR szwEnabled[] = {'E','n','a','b','l','e','d',0};
static const WCHAR szwEnable[] = {'E','n','a','b','l','e',0};
static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
static const WCHAR szwAssemblies[] = {'A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szwDefault[] = {'D','e','f','a','u','l','t',0};
static const WCHAR szwProfile[] = {'P','r','o','f','i','l','e',0};
static const WCHAR szwDefaultFmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
typedef struct tagInputProcessorProfilesSink {
struct list entry;
union {
@@ -144,7 +149,7 @@ static void add_userkey( REFCLSID rclsid, LANGID langid,
if (!res && disposition == REG_CREATED_NEW_KEY)
{
DWORD zero = 0x0;
RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
}
if (!res)
@@ -278,7 +283,7 @@ static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
if (disposition == REG_CREATED_NEW_KEY)
RegSetValueExW(fmtkey, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
RegCloseKey(fmtkey);
add_userkey(rclsid, langid, guidProfile);
@@ -312,18 +317,91 @@ static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
CLSID *pclsid, GUID *pguidProfile)
{
WCHAR fullkey[168];
WCHAR buf[39];
HKEY hkey;
DWORD count;
ULONG res;
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("%p) %x %s %p %p\n",This, langid, debugstr_guid(catid),pclsid,pguidProfile);
if (!catid || !pclsid || !pguidProfile)
return E_INVALIDARG;
StringFromGUID2(catid, buf, 39);
sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);
if (RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE,
&hkey ) != ERROR_SUCCESS)
return S_FALSE;
count = sizeof(buf);
res = RegQueryValueExW(hkey, szwDefault, 0, NULL, (LPBYTE)buf, &count);
if (res != ERROR_SUCCESS)
{
RegCloseKey(hkey);
return S_FALSE;
}
CLSIDFromString(buf,pclsid);
res = RegQueryValueExW(hkey, szwProfile, 0, NULL, (LPBYTE)buf, &count);
if (res == ERROR_SUCCESS)
CLSIDFromString(buf,pguidProfile);
RegCloseKey(hkey);
return S_OK;
}
static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
REFGUID guidProfiles)
{
WCHAR fullkey[168];
WCHAR buf[39];
HKEY hkey;
GUID catid;
HRESULT hr;
ITfCategoryMgr *catmgr;
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
&GUID_TFCAT_TIP_SPEECH,
&GUID_TFCAT_TIP_HANDWRITING };
TRACE("%p) %x %s %s\n",This, langid, debugstr_guid(rclsid),debugstr_guid(guidProfiles));
if (!rclsid || !guidProfiles)
return E_INVALIDARG;
hr = CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
if (FAILED(hr))
return hr;
if (ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
&catid, tipcats, 3) != S_OK)
hr = ITfCategoryMgr_FindClosestCategory(catmgr, rclsid,
&catid, NULL, 0);
ITfCategoryMgr_Release(catmgr);
if (FAILED(hr))
return E_FAIL;
StringFromGUID2(&catid, buf, 39);
sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf);
if (RegCreateKeyExW(HKEY_CURRENT_USER, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
NULL, &hkey, NULL ) != ERROR_SUCCESS)
return E_FAIL;
StringFromGUID2(rclsid, buf, 39);
RegSetValueExW(hkey, szwDefault, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
StringFromGUID2(guidProfiles, buf, 39);
RegSetValueExW(hkey, szwProfile, 0, REG_SZ, (LPBYTE)buf, sizeof(buf));
RegCloseKey(hkey);
return S_OK;
}
static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
@@ -413,8 +491,22 @@ static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
ITfInputProcessorProfiles *iface, LANGID langid)
{
struct list *cursor;
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
BOOL accept;
FIXME("STUB:(%p)\n",This);
LIST_FOR_EACH(cursor, &This->LanguageProfileNotifySink)
{
InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
accept = TRUE;
ITfLanguageProfileNotifySink_OnLanguageChange(sink->interfaces.pITfLanguageProfileNotifySink, langid, &accept);
if (!accept)
return E_FAIL;
}
/* TODO: On successful language change call OnLanguageChanged sink */
return E_NOTIMPL;
}
@@ -422,8 +514,11 @@ static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
{
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
FIXME("Semi-STUB:(%p)\n",This);
*ppLangId = CoTaskMemAlloc(sizeof(LANGID));
**ppLangId = This->currentLanguage;
*pulCount = 1;
return S_OK;
}
static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
@@ -456,7 +551,7 @@ static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
if (!res)
{
RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
RegCloseKey(key);
}
else
@@ -490,7 +585,7 @@ static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
if (!res)
{
DWORD count = sizeof(DWORD);
res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
RegCloseKey(key);
}
@@ -501,7 +596,7 @@ static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
if (!res)
{
DWORD count = sizeof(DWORD);
res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count);
RegCloseKey(key);
}
}
@@ -533,7 +628,7 @@ static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
if (!res)
{
RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
RegCloseKey(key);
}
else
+11 -1
View File
@@ -33,7 +33,6 @@
#include "shlwapi.h"
#include "shlguid.h"
#include "comcat.h"
#include "initguid.h"
#include "msctf.h"
#include "msctf_internal.h"
@@ -74,8 +73,10 @@ static UINT activated = 0;
DWORD tlsIndex = 0;
TfClientId processId = 0;
ITfCompartmentMgr *globalCompartmentMgr = NULL;
const WCHAR szwSystemTIPKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F','\\','T','I','P',0};
const WCHAR szwSystemCTFKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F',0};
typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut);
@@ -598,3 +599,12 @@ HRESULT WINAPI SetInputScopes(HWND hwnd, const INT *pInputScopes,
return S_OK;
}
/***********************************************************************
* TF_CreateInputProcessorProfiles(MSCTF.@)
*/
HRESULT WINAPI TF_CreateInputProcessorProfiles(
ITfInputProcessorProfiles **ppipr)
{
return InputProcessorProfiles_Constructor(NULL,(IUnknown**)ppipr);
}
+7
View File
@@ -9,6 +9,7 @@
<define name="__WINESRC__" />
<redefine name="_WIN32_WINNT">0x600</redefine>
<file>categorymgr.c</file>
<file>compartmentmgr.c</file>
<file>context.c</file>
<file>documentmgr.c</file>
<file>inputprocessor.c</file>
@@ -20,12 +21,18 @@
<library>wine</library>
<library>uuid</library>
<library>ole32</library>
<library>oleaut32</library>
<library>user32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>msctf_local_interface</library>
<library>textstor_local_interface</library>
<library>ntdll</library>
</module>
<module name="msctf_local_interface" type="idlinterface">
<file>msctf_local.idl</file>
</module>
<module name="textstor_local_interface" type="idlinterface">
<file>textstor_local.idl</file>
</module>
</group>
+1 -1
View File
@@ -11,7 +11,7 @@
@ stub TF_CreateCategoryMgr
@ stub TF_CreateCicLoadMutex
@ stub TF_CreateDisplayAttributeMgr
@ stub TF_CreateInputProcessorProfiles
@ stdcall TF_CreateInputProcessorProfiles(ptr)
@ stub TF_CreateLangBarItemMgr
@ stub TF_CreateLangBarMgr
@ stdcall TF_CreateThreadMgr(ptr)
+9 -2
View File
@@ -26,19 +26,25 @@
#define COOKIE_MAGIC_GUIDATOM 0x0030
#define COOKIE_MAGIC_IPPSINK 0x0040
#define COOKIE_MAGIC_EDITCOOKIE 0x0050
#define COOKIE_MAGIC_COMPARTMENTSINK 0x0060
extern DWORD tlsIndex;
extern TfClientId processId;
extern ITfCompartmentMgr *globalCompartmentMgr;
extern HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **ppOut);
extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore);
extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore);
extern HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
extern HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
extern HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut);
extern HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut);
extern HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *This);
extern HRESULT Context_Initialize(ITfContext *cxt);
extern HRESULT Context_Initialize(ITfContext *cxt, ITfDocumentMgr *manager);
extern HRESULT Context_Uninitialize(ITfContext *cxt);
extern void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr);
extern HRESULT TF_SELECTION_to_TS_SELECTION_ACP(const TF_SELECTION *tf, TS_SELECTION_ACP *tsAcp);
/* cookie function */
extern DWORD generate_Cookie(DWORD magic, LPVOID data);
@@ -58,4 +64,5 @@ extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sin
extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink);
extern const WCHAR szwSystemTIPKey[];
extern const WCHAR szwSystemCTFKey[];
#endif /* __WINE_MSCTF_I_H */
+33 -2
View File
@@ -201,8 +201,21 @@ static HRESULT WINAPI Range_Collapse(ITfRange *iface, TfEditCookie ec,
TfAnchor aPos)
{
Range *This = (Range *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %i %i\n",This,ec,aPos);
switch (aPos)
{
case TF_ANCHOR_START:
This->anchorEnd = This->anchorStart;
break;
case TF_ANCHOR_END:
This->anchorStart = This->anchorEnd;
break;
default:
return E_INVALIDARG;
}
return S_OK;
}
static HRESULT WINAPI Range_IsEqualStart(ITfRange *iface, TfEditCookie ec,
@@ -331,3 +344,21 @@ HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD l
return S_OK;
}
/* Internal conversion functions */
HRESULT TF_SELECTION_to_TS_SELECTION_ACP(const TF_SELECTION *tf, TS_SELECTION_ACP *tsAcp)
{
Range *This;
if (!tf || !tsAcp || !tf->range)
return E_INVALIDARG;
This = (Range *)tf->range;
tsAcp->acpStart = This->anchorStart;
tsAcp->acpEnd = This->anchorEnd;
tsAcp->style.ase = tf->style.ase;
tsAcp->style.fInterimChar = tf->style.fInterimChar;
return S_OK;
}
@@ -0,0 +1,2 @@
#include "textstor.idl"
+357 -10
View File
@@ -65,6 +65,19 @@ typedef struct tagPreservedKey
TfClientId tid;
} PreservedKey;
typedef struct tagDocumentMgrs
{
struct list entry;
ITfDocumentMgr *docmgr;
} DocumentMgrEntry;
typedef struct tagAssociatedWindow
{
struct list entry;
HWND hwnd;
ITfDocumentMgr *docmgr;
} AssociatedWindow;
typedef struct tagACLMulti {
const ITfThreadMgrVtbl *ThreadMgrVtbl;
const ITfSourceVtbl *SourceVtbl;
@@ -78,6 +91,9 @@ typedef struct tagACLMulti {
/* const ITfSourceSingleVtbl *SourceSingleVtbl; */
LONG refCount;
/* Aggregation */
ITfCompartmentMgr *CompartmentMgr;
const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
ITfDocumentMgr *focus;
@@ -87,6 +103,10 @@ typedef struct tagACLMulti {
CLSID forgroundTextService;
struct list CurrentPreservedKeys;
struct list CreatedDocumentMgrs;
struct list AssociatedFocusWindows;
HHOOK focusHook;
/* kept as separate lists to reduce unnecessary iterations */
struct list ActiveLanguageProfileNotifySink;
@@ -97,6 +117,17 @@ typedef struct tagACLMulti {
struct list ThreadMgrEventSink;
} ThreadMgr;
typedef struct tagEnumTfDocumentMgr {
const IEnumTfDocumentMgrsVtbl *Vtbl;
LONG refCount;
struct list *index;
struct list *head;
} EnumTfDocumentMgr;
static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut);
LRESULT CALLBACK ThreadFocusHookProc(int nCode, WPARAM wParam, LPARAM lParam);
static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
{
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
@@ -122,6 +153,22 @@ static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
}
static HRESULT SetupWindowsHook(ThreadMgr *This)
{
if (!This->focusHook)
{
This->focusHook = SetWindowsHookExW(WH_CBT, ThreadFocusHookProc, 0,
GetCurrentThreadId());
if (!This->focusHook)
{
ERR("Unable to set focus hook\n");
return E_FAIL;
}
return S_OK;
}
return S_FALSE;
}
static void free_sink(ThreadMgrSink *sink)
{
IUnknown_Release(sink->interfaces.pIUnknown);
@@ -132,6 +179,10 @@ static void ThreadMgr_Destructor(ThreadMgr *This)
{
struct list *cursor, *cursor2;
/* unhook right away */
if (This->focusHook)
UnhookWindowsHookEx(This->focusHook);
TlsSetValue(tlsIndex,NULL);
TRACE("destroying %p\n", This);
if (This->focus)
@@ -183,6 +234,23 @@ static void ThreadMgr_Destructor(ThreadMgr *This)
HeapFree(GetProcessHeap(),0,key);
}
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CreatedDocumentMgrs)
{
DocumentMgrEntry *mgr = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
list_remove(cursor);
FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
HeapFree(GetProcessHeap(),0,mgr);
}
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
{
AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
list_remove(cursor);
HeapFree(GetProcessHeap(),0,wnd);
}
CompartmentMgr_Destructor(This->CompartmentMgr);
HeapFree(GetProcessHeap(),0,This);
}
@@ -211,6 +279,10 @@ static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid,
{
*ppvOut = &This->ClientIdVtbl;
}
else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
{
*ppvOut = This->CompartmentMgr;
}
if (*ppvOut)
{
@@ -294,16 +366,37 @@ static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocum
**ppdim)
{
ThreadMgr *This = (ThreadMgr *)iface;
DocumentMgrEntry *mgrentry;
HRESULT hr;
TRACE("(%p)\n",iface);
return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
mgrentry = HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry));
if (mgrentry == NULL)
return E_OUTOFMEMORY;
hr = DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
if (SUCCEEDED(hr))
{
mgrentry->docmgr = *ppdim;
list_add_head(&This->CreatedDocumentMgrs,&mgrentry->entry);
}
else
HeapFree(GetProcessHeap(),0,mgrentry);
return hr;
}
static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
**ppEnum)
{
ThreadMgr *This = (ThreadMgr *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %p\n",This,ppEnum);
if (!ppEnum)
return E_INVALIDARG;
return EnumTfDocumentMgr_Constructor(&This->CreatedDocumentMgrs, ppEnum);
}
static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
@@ -334,7 +427,9 @@ static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *p
TRACE("(%p) %p\n",This,pdimFocus);
if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
if (!pdimFocus)
check = NULL;
else if (FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
return E_INVALIDARG;
ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
@@ -349,16 +444,53 @@ static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *p
static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
{
struct list *cursor, *cursor2;
ThreadMgr *This = (ThreadMgr *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
AssociatedWindow *wnd;
TRACE("(%p) %p %p %p\n",This,hwnd,pdimNew,ppdimPrev);
if (!ppdimPrev)
return E_INVALIDARG;
*ppdimPrev = NULL;
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
{
wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
if (wnd->hwnd == hwnd)
{
if (wnd->docmgr)
ITfDocumentMgr_AddRef(wnd->docmgr);
*ppdimPrev = wnd->docmgr;
wnd->docmgr = pdimNew;
if (GetFocus() == hwnd)
ThreadMgr_SetFocus(iface,pdimNew);
return S_OK;
}
}
wnd = HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow));
wnd->hwnd = hwnd;
wnd->docmgr = pdimNew;
list_add_head(&This->AssociatedFocusWindows,&wnd->entry);
if (GetFocus() == hwnd)
ThreadMgr_SetFocus(iface,pdimNew);
SetupWindowsHook(This);
return S_OK;
}
static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
{
HWND focus;
ThreadMgr *This = (ThreadMgr *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
TRACE("(%p) %p\n",This,pfThreadFocus);
focus = GetFocus();
*pfThreadFocus = (focus == NULL);
return S_OK;
}
static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
@@ -381,8 +513,22 @@ static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
ITfCompartmentMgr **ppCompMgr)
{
ThreadMgr *This = (ThreadMgr *)iface;
FIXME("STUB:(%p)\n",This);
return E_NOTIMPL;
HRESULT hr;
TRACE("(%p) %p\n",This, ppCompMgr);
if (!ppCompMgr)
return E_INVALIDARG;
if (!globalCompartmentMgr)
{
hr = CompartmentMgr_Constructor(NULL,&IID_ITfCompartmentMgr,(IUnknown**)&globalCompartmentMgr);
if (FAILED(hr))
return hr;
}
ITfCompartmentMgr_AddRef(globalCompartmentMgr);
*ppCompMgr = globalCompartmentMgr;
return S_OK;
}
static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
@@ -1054,7 +1200,11 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
This->refCount = 1;
TlsSetValue(tlsIndex,This);
CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
list_init(&This->CurrentPreservedKeys);
list_init(&This->CreatedDocumentMgrs);
list_init(&This->AssociatedFocusWindows);
list_init(&This->ActiveLanguageProfileNotifySink);
list_init(&This->DisplayAttributeNotifySink);
@@ -1067,3 +1217,200 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
*ppOut = (IUnknown *)This;
return S_OK;
}
/**************************************************
* IEnumTfDocumentMgrs implementaion
**************************************************/
static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr *This)
{
TRACE("destroying %p\n", This);
HeapFree(GetProcessHeap(),0,This);
}
static HRESULT WINAPI EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs *iface, REFIID iid, LPVOID *ppvOut)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
*ppvOut = NULL;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfDocumentMgrs))
{
*ppvOut = This;
}
if (*ppvOut)
{
IUnknown_AddRef(iface);
return S_OK;
}
WARN("unsupported interface: %s\n", debugstr_guid(iid));
return E_NOINTERFACE;
}
static ULONG WINAPI EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs *iface)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr*)iface;
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
ULONG ret;
ret = InterlockedDecrement(&This->refCount);
if (ret == 0)
EnumTfDocumentMgr_Destructor(This);
return ret;
}
static HRESULT WINAPI EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs *iface,
ULONG ulCount, ITfDocumentMgr **rgDocumentMgr, ULONG *pcFetched)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
ULONG fetched = 0;
TRACE("(%p)\n",This);
if (rgDocumentMgr == NULL) return E_POINTER;
while (fetched < ulCount)
{
DocumentMgrEntry *mgrentry;
if (This->index == NULL)
break;
mgrentry = LIST_ENTRY(This->index,DocumentMgrEntry,entry);
if (mgrentry == NULL)
break;
*rgDocumentMgr = mgrentry->docmgr;
ITfDocumentMgr_AddRef(*rgDocumentMgr);
This->index = list_next(This->head, This->index);
++fetched;
++rgDocumentMgr;
}
if (pcFetched) *pcFetched = fetched;
return fetched == ulCount ? S_OK : S_FALSE;
}
static HRESULT WINAPI EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs* iface, ULONG celt)
{
INT i;
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
TRACE("(%p)\n",This);
for(i = 0; i < celt && This->index != NULL; i++)
This->index = list_next(This->head, This->index);
return S_OK;
}
static HRESULT WINAPI EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs* iface)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
TRACE("(%p)\n",This);
This->index = list_head(This->head);
return S_OK;
}
static HRESULT WINAPI EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs *iface,
IEnumTfDocumentMgrs **ppenum)
{
EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
HRESULT res;
TRACE("(%p)\n",This);
if (ppenum == NULL) return E_POINTER;
res = EnumTfDocumentMgr_Constructor(This->head, ppenum);
if (SUCCEEDED(res))
{
EnumTfDocumentMgr *new_This = (EnumTfDocumentMgr *)*ppenum;
new_This->index = This->index;
}
return res;
}
static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl ={
EnumTfDocumentMgr_QueryInterface,
EnumTfDocumentMgr_AddRef,
EnumTfDocumentMgr_Release,
EnumTfDocumentMgr_Clone,
EnumTfDocumentMgr_Next,
EnumTfDocumentMgr_Reset,
EnumTfDocumentMgr_Skip
};
static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut)
{
EnumTfDocumentMgr *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfDocumentMgr));
if (This == NULL)
return E_OUTOFMEMORY;
This->Vtbl= &IEnumTfDocumentMgrs_Vtbl;
This->refCount = 1;
This->head = head;
This->index = list_head(This->head);
TRACE("returning %p\n", This);
*ppOut = (IEnumTfDocumentMgrs*)This;
return S_OK;
}
void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr)
{
ThreadMgr *This = (ThreadMgr *)tm;
struct list *cursor;
LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs)
{
DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
if (mgrentry->docmgr == mgr)
{
list_remove(cursor);
HeapFree(GetProcessHeap(),0,mgrentry);
return;
}
}
FIXME("ITfDocumenMgr %p not found in this thread\n",mgr);
}
LRESULT CALLBACK ThreadFocusHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
ThreadMgr *This;
This = TlsGetValue(tlsIndex);
if (!This)
{
ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
return 0;
}
if (!This->focusHook)
{
ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
return 0;
}
if (nCode == HCBT_SETFOCUS) /* focus change within our thread */
{
struct list *cursor;
LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows)
{
AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
if (wnd->hwnd == (HWND)wParam)
{
TRACE("Triggering Associated window focus\n");
if (This->focus != wnd->docmgr)
ThreadMgr_SetFocus((ITfThreadMgr*)This, wnd->docmgr);
break;
}
}
}
return CallNextHookEx(This->focusHook, nCode, wParam, lParam);
}
+280 -59
View File
@@ -35,12 +35,14 @@ typedef struct {
DISPID id;
BSTR name;
tid_t tid;
int func_disp_idx;
} func_info_t;
struct dispex_data_t {
DWORD func_cnt;
func_info_t *funcs;
func_info_t **name_table;
DWORD func_disp_cnt;
struct list entry;
};
@@ -50,10 +52,20 @@ typedef struct {
LPWSTR name;
} dynamic_prop_t;
typedef struct {
DispatchEx dispex;
const IUnknownVtbl *lpIUnknownVtbl;
DispatchEx *obj;
func_info_t *info;
} func_disp_t;
#define FUNCUNKNOWN(x) ((IUnknown*) &(x)->lpIUnknownVtbl)
struct dispex_dynamic_data_t {
DWORD buf_size;
DWORD prop_cnt;
dynamic_prop_t *props;
func_disp_t **func_disps;
};
#define DISPID_DYNPROP_0 0x50000000
@@ -188,22 +200,23 @@ void release_typelib(void)
ITypeLib_Release(typelib);
}
static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, DISPID id, ITypeInfo *dti)
static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti)
{
HRESULT hres;
if(data->func_cnt && data->funcs[data->func_cnt-1].id == id)
if(data->func_cnt && data->funcs[data->func_cnt-1].id == desc->memid)
return;
if(data->func_cnt == *size)
data->funcs = heap_realloc(data->funcs, (*size <<= 1)*sizeof(func_info_t));
hres = ITypeInfo_GetDocumentation(dti, id, &data->funcs[data->func_cnt].name, NULL, NULL, NULL);
hres = ITypeInfo_GetDocumentation(dti, desc->memid, &data->funcs[data->func_cnt].name, NULL, NULL, NULL);
if(FAILED(hres))
return;
data->funcs[data->func_cnt].id = id;
data->funcs[data->func_cnt].id = desc->memid;
data->funcs[data->func_cnt].tid = tid;
data->funcs[data->func_cnt].func_disp_idx = desc->invkind == INVOKE_FUNC ? data->func_disp_cnt++ : -1;
data->func_cnt++;
}
@@ -237,6 +250,7 @@ static dispex_data_t *preprocess_dispex_data(DispatchEx *This)
data = heap_alloc(sizeof(dispex_data_t));
data->func_cnt = 0;
data->func_disp_cnt = 0;
data->funcs = heap_alloc(size*sizeof(func_info_t));
list_add_tail(&dispex_data_list, &data->entry);
@@ -251,7 +265,7 @@ static dispex_data_t *preprocess_dispex_data(DispatchEx *This)
if(FAILED(hres))
break;
add_func_info(data, &size, *tid, funcdesc->memid, dti);
add_func_info(data, &size, *tid, funcdesc, dti);
ITypeInfo_ReleaseFuncDesc(ti, funcdesc);
}
@@ -343,55 +357,56 @@ static inline BOOL is_dynamic_dispid(DISPID id)
return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
}
static inline dispex_dynamic_data_t *get_dynamic_data(DispatchEx *This, BOOL alloc)
{
return !alloc || This->dynamic_data
? This->dynamic_data
: (This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)));
}
static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, BOOL alloc, dynamic_prop_t **ret)
{
dispex_dynamic_data_t *data = This->dynamic_data;
dispex_dynamic_data_t *data = get_dynamic_data(This, alloc);
unsigned i;
if(data) {
unsigned i;
if(!data) {
if(alloc)
return E_OUTOFMEMORY;
for(i=0; i < data->prop_cnt; i++) {
if(!strcmpW(data->props[i].name, name)) {
*ret = data->props+i;
return S_OK;
}
TRACE("not found %s\n", debugstr_w(name));
return DISP_E_UNKNOWNNAME;
}
for(i=0; i < data->prop_cnt; i++) {
if(!strcmpW(data->props[i].name, name)) {
*ret = data->props+i;
return S_OK;
}
}
if(alloc) {
TRACE("creating dynamic prop %s\n", debugstr_w(name));
TRACE("creating dynamic prop %s\n", debugstr_w(name));
if(!data) {
data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t));
if(!data)
return E_OUTOFMEMORY;
}
if(!data->buf_size) {
data->props = heap_alloc(sizeof(dynamic_prop_t)*4);
if(!data->props)
return E_OUTOFMEMORY;
data->buf_size = 4;
}else if(data->buf_size == data->prop_cnt) {
dynamic_prop_t *new_props;
if(!data->buf_size) {
data->props = heap_alloc(sizeof(dynamic_prop_t)*4);
if(!data->props)
return E_OUTOFMEMORY;
data->buf_size = 4;
}else if(data->buf_size == data->prop_cnt) {
dynamic_prop_t *new_props;
new_props = heap_realloc(data->props, sizeof(dynamic_prop_t)*(data->buf_size<<1));
if(!new_props)
return E_OUTOFMEMORY;
new_props = heap_realloc(data->props, sizeof(dynamic_prop_t)*(data->buf_size<<1));
if(!new_props)
return E_OUTOFMEMORY;
data->props = new_props;
data->buf_size <<= 1;
}
data->props[data->prop_cnt].name = heap_strdupW(name);
VariantInit(&data->props[data->prop_cnt].var);
*ret = data->props + data->prop_cnt++;
return S_OK;
data->props = new_props;
data->buf_size <<= 1;
}
TRACE("not found %s\n", debugstr_w(name));
return DISP_E_UNKNOWNNAME;
data->props[data->prop_cnt].name = heap_strdupW(name);
VariantInit(&data->props[data->prop_cnt].var);
*ret = data->props + data->prop_cnt++;
return S_OK;
}
HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VARIANT **ret)
@@ -407,6 +422,191 @@ HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VA
return S_OK;
}
static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
if(This->data->vtbl && This->data->vtbl->value)
return This->data->vtbl->value(This->outer, lcid, flags, params, res, ei, caller);
switch(flags) {
case DISPATCH_PROPERTYGET:
V_VT(res) = VT_BSTR;
V_BSTR(res) = SysAllocString(objectW);
if(!V_BSTR(res))
return E_OUTOFMEMORY;
break;
default:
FIXME("Unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
EXCEPINFO *ei)
{
ITypeInfo *ti;
IUnknown *unk;
UINT argerr=0;
HRESULT hres;
hres = get_typeinfo(func->tid, &ti);
if(FAILED(hres)) {
ERR("Could not get type info: %08x\n", hres);
return hres;
}
hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&unk);
if(FAILED(hres)) {
ERR("Could not get iface %s: %08x\n", debugstr_guid(tid_ids[func->tid]), hres);
return E_FAIL;
}
hres = ITypeInfo_Invoke(ti, unk, func->id, flags, dp, res, ei, &argerr);
IUnknown_Release(unk);
return hres;
}
#define FUNCTION_THIS(iface) DEFINE_THIS(func_disp_t, IUnknown, iface)
static HRESULT WINAPI Function_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
func_disp_t *This = FUNCTION_THIS(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = FUNCUNKNOWN(This);
}else if(dispex_query_interface(&This->dispex, riid, ppv)) {
return *ppv ? S_OK : E_NOINTERFACE;
}else {
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI Function_AddRef(IUnknown *iface)
{
func_disp_t *This = FUNCTION_THIS(iface);
TRACE("(%p)\n", This);
return IDispatchEx_AddRef(DISPATCHEX(This->obj));
}
static ULONG WINAPI Function_Release(IUnknown *iface)
{
func_disp_t *This = FUNCTION_THIS(iface);
TRACE("(%p)\n", This);
return IDispatchEx_Release(DISPATCHEX(This->obj));
}
static HRESULT function_value(IUnknown *iface, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
func_disp_t *This = FUNCTION_THIS(iface);
HRESULT hres;
switch(flags) {
case DISPATCH_METHOD:
hres = typeinfo_invoke(This->obj, This->info, flags, params, res, ei);
break;
default:
FIXME("Unimplemented flags %x\n", flags);
hres = E_NOTIMPL;
}
return hres;
}
#undef FUNCTION_THIS
static const IUnknownVtbl FunctionUnkVtbl = {
Function_QueryInterface,
Function_AddRef,
Function_Release
};
static const dispex_static_data_vtbl_t function_dispex_vtbl = {
function_value,
NULL,
NULL
};
static dispex_static_data_t function_dispex = {
&function_dispex_vtbl,
LAST_tid,
NULL,
NULL
};
static func_disp_t *create_func_disp(DispatchEx *obj, func_info_t *info)
{
func_disp_t *ret;
ret = heap_alloc_zero(sizeof(func_disp_t));
if(!ret)
return NULL;
ret->lpIUnknownVtbl = &FunctionUnkVtbl;
init_dispex(&ret->dispex, FUNCUNKNOWN(ret), &function_dispex);
ret->obj = obj;
ret->info = info;
return ret;
}
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
EXCEPINFO *ei)
{
HRESULT hres;
switch(flags) {
case DISPATCH_METHOD:
hres = typeinfo_invoke(This, func, flags, dp, res, ei);
break;
case DISPATCH_PROPERTYGET: {
dispex_dynamic_data_t *dynamic_data;
dynamic_data = get_dynamic_data(This, TRUE);
if(!dynamic_data)
return E_OUTOFMEMORY;
if(!dynamic_data->func_disps) {
dynamic_data->func_disps = heap_alloc_zero(This->data->data->func_disp_cnt * sizeof(func_disp_t*));
if(!dynamic_data->func_disps)
return E_OUTOFMEMORY;
}
if(!dynamic_data->func_disps[func->func_disp_idx]) {
dynamic_data->func_disps[func->func_disp_idx] = create_func_disp(This, func);
if(!dynamic_data->func_disps[func->func_disp_idx])
return E_OUTOFMEMORY;
}
V_VT(res) = VT_DISPATCH;
V_DISPATCH(res) = (IDispatch*)DISPATCHEX(&dynamic_data->func_disps[func->func_disp_idx]->dispex);
IDispatch_AddRef(V_DISPATCH(res));
hres = S_OK;
break;
}
default:
FIXME("Unimplemented flags %x\n", flags);
case DISPATCH_PROPERTYPUT:
hres = E_NOTIMPL;
}
return hres;
}
#define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
@@ -547,15 +747,15 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
DispatchEx *This = DISPATCHEX_THIS(iface);
IUnknown *unk;
ITypeInfo *ti;
dispex_data_t *data;
UINT argerr=0;
int min, max, n;
HRESULT hres;
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
if(id == DISPID_VALUE)
return dispex_value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
if(is_custom_dispid(id) && This->data->vtbl && This->data->vtbl->invoke)
return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
@@ -648,21 +848,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
return DISP_E_UNKNOWNNAME;
}
hres = get_typeinfo(data->funcs[n].tid, &ti);
if(FAILED(hres)) {
ERR("Could not get type info: %08x\n", hres);
return hres;
}
if(data->funcs[n].func_disp_idx == -1)
hres = typeinfo_invoke(This, data->funcs+n, wFlags, pdp, pvarRes, pei);
else
hres = function_invoke(This, data->funcs+n, wFlags, pdp, pvarRes, pei);
hres = IUnknown_QueryInterface(This->outer, tid_ids[data->funcs[n].tid], (void**)&unk);
if(FAILED(hres)) {
ERR("Could not get iface %s: %08x\n", debugstr_guid(tid_ids[data->funcs[n].tid]), hres);
return E_FAIL;
}
hres = ITypeInfo_Invoke(ti, unk, id, wFlags, pdp, pvarRes, pei, &argerr);
IUnknown_Release(unk);
return hres;
}
@@ -756,9 +946,40 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
return TRUE;
}
void release_dispex(DispatchEx *This)
{
dynamic_prop_t *prop;
if(!This->dynamic_data)
return;
for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
VariantClear(&prop->var);
heap_free(prop->name);
}
heap_free(This->dynamic_data->props);
if(This->dynamic_data->func_disps) {
unsigned i;
for(i=0; i < This->data->data->func_disp_cnt; i++) {
if(This->dynamic_data->func_disps[i]) {
release_dispex(&This->dynamic_data->func_disps[i]->dispex);
heap_free(This->dynamic_data->func_disps[i]);
}
}
heap_free(This->dynamic_data->func_disps);
}
heap_free(This->dynamic_data);
}
void init_dispex(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data)
{
dispex->lpIDispatchExVtbl = &DispatchExVtbl;
dispex->outer = outer;
dispex->data = data;
dispex->dynamic_data = NULL;
}
+23 -20
View File
@@ -90,6 +90,7 @@ static ULONG WINAPI HTMLCurrentStyle_Release(IHTMLCurrentStyle *iface)
if(!ref) {
if(This->nsstyle)
nsIDOMCSSStyleDeclaration_Release(This->nsstyle);
release_dispex(&This->dispex);
heap_free(This);
}
@@ -144,15 +145,15 @@ static HRESULT WINAPI HTMLCurrentStyle_get_styleFloat(IHTMLCurrentStyle *iface,
static HRESULT WINAPI HTMLCurrentStyle_get_color(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_COLOR, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_backgroundColor(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_COLOR, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_fontFamily(IHTMLCurrentStyle *iface, BSTR *p)
@@ -279,29 +280,29 @@ static HRESULT WINAPI HTMLCurrentStyle_get_borderLeftStyle(IHTMLCurrentStyle *if
static HRESULT WINAPI HTMLCurrentStyle_get_borderTopWidth(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_borderRightWidth(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_borderBottomWidth(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_borderLeftWidth(IHTMLCurrentStyle *iface, VARIANT *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, p, 0);
}
static HRESULT WINAPI HTMLCurrentStyle_get_left(IHTMLCurrentStyle *iface, VARIANT *p)
@@ -386,8 +387,10 @@ static HRESULT WINAPI HTMLCurrentStyle_get_display(IHTMLCurrentStyle *iface, BST
static HRESULT WINAPI HTMLCurrentStyle_get_visibility(IHTMLCurrentStyle *iface, BSTR *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr(This->nsstyle, STYLEID_VISIBILITY, p);
}
static HRESULT WINAPI HTMLCurrentStyle_get_zIndex(IHTMLCurrentStyle *iface, VARIANT *p)
@@ -519,8 +522,8 @@ static HRESULT WINAPI HTMLCurrentStyle_get_clipLeft(IHTMLCurrentStyle *iface, VA
static HRESULT WINAPI HTMLCurrentStyle_get_overflow(IHTMLCurrentStyle *iface, BSTR *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW, p);
}
static HRESULT WINAPI HTMLCurrentStyle_get_pageBreakBefore(IHTMLCurrentStyle *iface, BSTR *p)
@@ -723,8 +726,8 @@ static HRESULT WINAPI HTMLCurrentStyle_get_borderColor(IHTMLCurrentStyle *iface,
static HRESULT WINAPI HTMLCurrentStyle_get_borderWidth(IHTMLCurrentStyle *iface, BSTR *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr(This->nsstyle, STYLEID_BORDER_WIDTH, p);
}
static HRESULT WINAPI HTMLCurrentStyle_get_padding(IHTMLCurrentStyle *iface, BSTR *p)
@@ -737,8 +740,8 @@ static HRESULT WINAPI HTMLCurrentStyle_get_padding(IHTMLCurrentStyle *iface, BST
static HRESULT WINAPI HTMLCurrentStyle_get_margin(IHTMLCurrentStyle *iface, BSTR *p)
{
HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr(This->nsstyle, STYLEID_MARGIN, p);
}
static HRESULT WINAPI HTMLCurrentStyle_get_accelerator(IHTMLCurrentStyle *iface, BSTR *p)
+22 -9
View File
@@ -215,6 +215,7 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
detach_selection(This);
detach_ranges(This);
release_nodes(This);
release_dispex(&This->dispex);
ConnectionPointContainer_Destroy(&This->cp_container);
@@ -900,17 +901,14 @@ static HRESULT WINAPI HTMLDocument_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
return E_NOTIMPL;
}
static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln)
{
HTMLDocument *This = HTMLDOC_THIS(iface);
nsAString nsstr;
VARIANT *var;
ULONG i;
ULONG i, argc;
nsresult nsres;
HRESULT hres;
TRACE("(%p)->(%p)\n", iface, psarray);
if(!This->nsdoc) {
WARN("NULL nsdoc\n");
return E_UNEXPECTED;
@@ -929,10 +927,14 @@ static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarr
nsAString_Init(&nsstr, NULL);
for(i=0; i < psarray->rgsabound[0].cElements; i++) {
argc = psarray->rgsabound[0].cElements;
for(i=0; i < argc; i++) {
if(V_VT(var+i) == VT_BSTR) {
nsAString_SetData(&nsstr, V_BSTR(var+i));
nsres = nsIDOMHTMLDocument_Write(This->nsdoc, &nsstr);
if(!ln || i != argc-1)
nsres = nsIDOMHTMLDocument_Write(This->nsdoc, &nsstr);
else
nsres = nsIDOMHTMLDocument_Writeln(This->nsdoc, &nsstr);
if(NS_FAILED(nsres))
ERR("Write failed: %08x\n", nsres);
}else {
@@ -946,11 +948,22 @@ static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarr
return S_OK;
}
static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
{
HTMLDocument *This = HTMLDOC_THIS(iface);
TRACE("(%p)->(%p)\n", iface, psarray);
return document_write(This, psarray, FALSE);
}
static HRESULT WINAPI HTMLDocument_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
{
HTMLDocument *This = HTMLDOC_THIS(iface);
FIXME("(%p)->(%p)\n", This, psarray);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, psarray);
return document_write(This, psarray, TRUE);
}
static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
+20 -2
View File
@@ -931,8 +931,26 @@ static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
{
HTMLElement *This = HTMLELEM_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
nsAString html_str;
HRESULT hres;
WARN("(%p)->(%p) semi-stub\n", This, p);
nsAString_Init(&html_str, NULL);
hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
if(SUCCEEDED(hres)) {
const PRUnichar *html;
nsAString_GetData(&html_str, &html);
*p = SysAllocString(html);
if(!*p)
hres = E_OUTOFMEMORY;
}
nsAString_Finish(&html_str);
TRACE("ret %s\n", debugstr_w(*p));
return S_OK;
}
static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
+2
View File
@@ -132,6 +132,7 @@ static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
if(!ref) {
IUnknown_Release(This->ref_unk);
release_dispex(&This->dispex);
heap_free(This->elems);
heap_free(This);
}
@@ -428,6 +429,7 @@ static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = {
};
static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = {
NULL,
HTMLElementCollection_get_dispid,
HTMLElementCollection_invoke
};
+3 -1
View File
@@ -176,8 +176,10 @@ static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
if(!ref) {
release_dispex(&This->dispex);
heap_free(This);
}
return ref;
}
+1 -1
View File
@@ -839,7 +839,7 @@ static HRESULT WINAPI HTMLInputTextElement_get_value(IHTMLInputTextElement *ifac
TRACE("(%p)->(%p)\n", This, p);
return IHTMLInputTextElement_get_value(HTMLINPUT(This), p);
return IHTMLInputElement_get_value(HTMLINPUT(This), p);
}
static HRESULT WINAPI HTMLInputTextElement_put_name(IHTMLInputTextElement *iface, BSTR v)
+88 -5
View File
@@ -23,7 +23,10 @@
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "wininet.h"
#include "shlwapi.h"
#include "wine/debug.h"
@@ -79,6 +82,7 @@ static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface)
if(!ref) {
if(This->doc && This->doc->location == This)
This->doc->location = NULL;
release_dispex(&This->dispex);
heap_free(This);
}
@@ -125,8 +129,20 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
{
HTMLLocation *This = HTMLLOCATION_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
if(!p)
return E_POINTER;
if(!This->doc || !This->doc->url) {
FIXME("No current URL\n");
return E_NOTIMPL;
}
*p = SysAllocString(This->doc->url);
return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v)
@@ -195,8 +211,41 @@ static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v)
static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p)
{
HTMLLocation *This = HTMLLOCATION_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
WCHAR buf[INTERNET_MAX_PATH_LENGTH];
URL_COMPONENTSW url = {sizeof(url)};
DWORD size = 0;
HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
if(!This->doc || !This->doc->url) {
FIXME("No current URL\n");
return E_NOTIMPL;
}
hres = CoInternetParseUrl(This->doc->url, PARSE_PATH_FROM_URL, 0, buf, sizeof(buf), &size, 0);
if(SUCCEEDED(hres)) {
*p = SysAllocString(buf);
if(!*p)
return E_OUTOFMEMORY;
return S_OK;
}
url.dwUrlPathLength = 1;
if(!InternetCrackUrlW(This->doc->url, 0, 0, &url)) {
FIXME("InternetCrackUrl failed\n");
return E_FAIL;
}
if(!url.dwUrlPathLength) {
*p = NULL;
return S_OK;
}
*p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength);
if(!*p)
return E_OUTOFMEMORY;
return S_OK;
}
static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v)
@@ -255,6 +304,34 @@ static HRESULT WINAPI HTMLLocation_toString(IHTMLLocation *iface, BSTR *String)
return E_NOTIMPL;
}
static HRESULT HTMLLocation_value(IUnknown *iface, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
HTMLLocation *This = HTMLLOCATION_THIS(iface);
HRESULT hres;
TRACE("(%p)\n", This);
switch(flags) {
case DISPATCH_PROPERTYGET: {
BSTR str;
hres = IHTMLLocation_get_href(HTMLLOCATION(This), &str);
if(FAILED(hres))
return hres;
V_VT(res) = VT_BSTR;
V_BSTR(res) = str;
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
#undef HTMLLOCATION_THIS
static const IHTMLLocationVtbl HTMLLocationVtbl = {
@@ -287,12 +364,18 @@ static const IHTMLLocationVtbl HTMLLocationVtbl = {
HTMLLocation_toString
};
static const dispex_static_data_vtbl_t HTMLLocation_dispex_vtbl = {
HTMLLocation_value,
NULL,
NULL
};
static const tid_t HTMLLocation_iface_tids[] = {
IHTMLLocation_tid,
0
};
static dispex_static_data_t HTMLLocation_dispex = {
NULL,
&HTMLLocation_dispex_vtbl,
DispHTMLLocation_tid,
NULL,
HTMLLocation_iface_tids
+2
View File
@@ -250,6 +250,7 @@ static const tid_t HTMLDOMChildrenCollection_iface_tids[] = {
};
static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = {
NULL,
HTMLDOMChildrenCollection_get_dispid,
HTMLDOMChildrenCollection_invoke
};
@@ -307,6 +308,7 @@ static ULONG WINAPI HTMLDOMNode_Release(IHTMLDOMNode *iface)
if(!ref) {
This->vtbl->destructor(This);
release_dispex(&This->dispex);
heap_free(This);
}
+23 -12
View File
@@ -59,6 +59,8 @@ static const WCHAR attrBorderLeft[] =
{'b','o','r','d','e','r','-','l','e','f','t',0};
static const WCHAR attrBorderLeftStyle[] =
{'b','o','r','d','e','r','-','l','e','f','t','-','s','t','y','l','e',0};
static const WCHAR attrBorderLeftWidth[] =
{'b','o','r','d','e','r','-','l','e','f','t','-','w','i','d','t','h',0};
static const WCHAR attrBorderRightStyle[] =
{'b','o','r','d','e','r','-','r','i','g','h','t','-','s','t','y','l','e',0};
static const WCHAR attrBorderRightWidth[] =
@@ -93,6 +95,8 @@ static const WCHAR attrHeight[] =
{'h','e','i','g','h','t',0};
static const WCHAR attrLeft[] =
{'l','e','f','t',0};
static const WCHAR attrLetterSpacing[] =
{'l','e','t','t','e','r','-','s','p','a','c','i','n','g',0};
static const WCHAR attrMargin[] =
{'m','a','r','g','i','n',0};
static const WCHAR attrMarginLeft[] =
@@ -119,6 +123,8 @@ static const WCHAR attrVisibility[] =
{'v','i','s','i','b','i','l','i','t','y',0};
static const WCHAR attrWidth[] =
{'w','i','d','t','h',0};
static const WCHAR attrWordSpacing[] =
{'w','o','r','d','-','s','p','a','c','i','n','g',0};
static const WCHAR attrWordWrap[] =
{'w','o','r','d','-','w','r','a','p',0};
static const WCHAR attrZIndex[] =
@@ -140,6 +146,7 @@ static const struct{
{attrBorderColor, DISPID_IHTMLSTYLE_BORDERCOLOR},
{attrBorderLeft, DISPID_IHTMLSTYLE_BORDERLEFT},
{attrBorderLeftStyle, DISPID_IHTMLSTYLE_BORDERLEFTSTYLE},
{attrBorderLeftWidth, DISPID_IHTMLSTYLE_BORDERLEFTWIDTH},
{attrBorderRightStyle, DISPID_IHTMLSTYLE_BORDERRIGHTSTYLE},
{attrBorderRightWidth, DISPID_IHTMLSTYLE_BORDERRIGHTWIDTH},
{attrBorderStyle, DISPID_IHTMLSTYLE_BORDERSTYLE},
@@ -157,6 +164,7 @@ static const struct{
{attrFontWeight, DISPID_IHTMLSTYLE_FONTWEIGHT},
{attrHeight, DISPID_IHTMLSTYLE_HEIGHT},
{attrLeft, DISPID_IHTMLSTYLE_LEFT},
{attrLetterSpacing, DISPID_IHTMLSTYLE_LETTERSPACING},
{attrMargin, DISPID_IHTMLSTYLE_MARGIN},
{attrMarginLeft, DISPID_IHTMLSTYLE_MARGINLEFT},
{attrMarginRight, DISPID_IHTMLSTYLE_MARGINRIGHT},
@@ -170,6 +178,7 @@ static const struct{
{attrVerticalAlign, DISPID_IHTMLSTYLE_VERTICALALIGN},
{attrVisibility, DISPID_IHTMLSTYLE_VISIBILITY},
{attrWidth, DISPID_IHTMLSTYLE_WIDTH},
{attrWordSpacing, DISPID_IHTMLSTYLE_WORDSPACING},
{attrWordWrap, DISPID_IHTMLSTYLE3_WORDWRAP},
{attrZIndex, DISPID_IHTMLSTYLE_ZINDEX}
};
@@ -545,6 +554,7 @@ static ULONG WINAPI HTMLStyle_Release(IHTMLStyle *iface)
if(!ref) {
if(This->nsstyle)
nsIDOMCSSStyleDeclaration_Release(This->nsstyle);
release_dispex(&This->dispex);
heap_free(This);
}
@@ -920,29 +930,29 @@ static HRESULT WINAPI HTMLStyle_get_backgroundPositionY(IHTMLStyle *iface, VARIA
static HRESULT WINAPI HTMLStyle_put_wordSpacing(IHTMLStyle *iface, VARIANT v)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(v%d)\n", This, V_VT(&v));
return E_NOTIMPL;
TRACE("(%p)->(v%d)\n", This, V_VT(&v));
return set_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, &v, 0);
}
static HRESULT WINAPI HTMLStyle_get_wordSpacing(IHTMLStyle *iface, VARIANT *p)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, p, 0);
}
static HRESULT WINAPI HTMLStyle_put_letterSpacing(IHTMLStyle *iface, VARIANT v)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(v%d)\n", This, V_VT(&v));
return E_NOTIMPL;
TRACE("(%p)->(v%d)\n", This, V_VT(&v));
return set_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, &v, 0);
}
static HRESULT WINAPI HTMLStyle_get_letterSpacing(IHTMLStyle *iface, VARIANT *p)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, p, 0);
}
static HRESULT WINAPI HTMLStyle_put_textDecoration(IHTMLStyle *iface, BSTR v)
@@ -1574,15 +1584,15 @@ static HRESULT WINAPI HTMLStyle_get_borderBottomWidth(IHTMLStyle *iface, VARIANT
static HRESULT WINAPI HTMLStyle_put_borderLeftWidth(IHTMLStyle *iface, VARIANT v)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(v%d)\n", This, V_VT(&v));
return E_NOTIMPL;
TRACE("(%p)->(v%d)\n", This, V_VT(&v));
return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, &v, 0);
}
static HRESULT WINAPI HTMLStyle_get_borderLeftWidth(IHTMLStyle *iface, VARIANT *p)
{
HTMLStyle *This = HTMLSTYLE_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, p, 0);
}
static HRESULT WINAPI HTMLStyle_put_borderStyle(IHTMLStyle *iface, BSTR v)
@@ -2601,6 +2611,7 @@ static const IHTMLStyleVtbl HTMLStyleVtbl = {
};
static const dispex_static_data_vtbl_t HTMLStyle_dispex_vtbl = {
NULL,
HTMLStyle_get_dispid,
NULL
};
+3
View File
@@ -47,6 +47,7 @@ typedef enum {
STYLEID_BORDER_COLOR,
STYLEID_BORDER_LEFT,
STYLEID_BORDER_LEFT_STYLE,
STYLEID_BORDER_LEFT_WIDTH,
STYLEID_BORDER_RIGHT_STYLE,
STYLEID_BORDER_RIGHT_WIDTH,
STYLEID_BORDER_STYLE,
@@ -64,6 +65,7 @@ typedef enum {
STYLEID_FONT_WEIGHT,
STYLEID_HEIGHT,
STYLEID_LEFT,
STYLEID_LETTER_SPACING,
STYLEID_MARGIN,
STYLEID_MARGIN_LEFT,
STYLEID_MARGIN_RIGHT,
@@ -77,6 +79,7 @@ typedef enum {
STYLEID_VERTICAL_ALIGN,
STYLEID_VISIBILITY,
STYLEID_WIDTH,
STYLEID_WORD_SPACING,
STYLEID_WORD_WRAP,
STYLEID_Z_INDEX
} styleid_t;
+11 -2
View File
@@ -93,6 +93,7 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
if(!ref) {
list_remove(&This->entry);
release_dispex(&This->dispex);
heap_free(This);
}
@@ -745,8 +746,16 @@ static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BS
static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
{
HTMLWindow *This = HTMLWINDOW2_THIS(iface);
FIXME("(%p)->(%p)\n", This, String);
return E_NOTIMPL;
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
TRACE("(%p)->(%p)\n", This, String);
if(!String)
return E_INVALIDARG;
*String = SysAllocString(objectW);
return *String ? S_OK : E_OUTOFMEMORY;
}
static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
+1
View File
@@ -77,6 +77,7 @@
<library>gdi32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>wininet</library>
<library>ntdll</library>
<dependency>mshtml_nsiface_header</dependency>
</module>
+7 -7
View File
@@ -33,9 +33,6 @@
#include "nsiface.h"
#define GENERATE_MSHTML_NS_FAILURE(code) \
((nsresult) ((PRUint32)(1<<31) | ((PRUint32)(0x45+6)<<16) | (PRUint32)(code)))
#define NS_OK ((nsresult)0x00000000L)
#define NS_ERROR_FAILURE ((nsresult)0x80004005L)
#define NS_NOINTERFACE ((nsresult)0x80004002L)
@@ -44,8 +41,6 @@
#define NS_ERROR_UNEXPECTED ((nsresult)0x8000ffffL)
#define NS_ERROR_UNKNOWN_PROTOCOL ((nsresult)0x804b0012L)
#define WINE_NS_LOAD_FROM_MONIKER GENERATE_MSHTML_NS_FAILURE(0)
#define NS_FAILED(res) ((res) & 0x80000000)
#define NS_SUCCEEDED(res) (!NS_FAILED(res))
@@ -132,6 +127,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t;
#define MSHTML_DISPID_CUSTOM_MAX 0x6fffffff
typedef struct {
HRESULT (*value)(IUnknown*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
HRESULT (*get_dispid)(IUnknown*,BSTR,DWORD,DISPID*);
HRESULT (*invoke)(IUnknown*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
} dispex_static_data_vtbl_t;
@@ -153,6 +149,7 @@ typedef struct {
} DispatchEx;
void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*);
void release_dispex(DispatchEx*);
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
@@ -363,11 +360,13 @@ struct NSContainer {
typedef struct {
const nsIHttpChannelVtbl *lpHttpChannelVtbl;
const nsIUploadChannelVtbl *lpUploadChannelVtbl;
const nsIHttpChannelInternalVtbl *lpIHttpChannelInternalVtbl;
LONG ref;
nsIChannel *channel;
nsIHttpChannel *http_channel;
nsIHttpChannelInternal *http_channel_internal;
nsIWineURI *uri;
nsIInputStream *post_data_stream;
nsILoadGroup *load_group;
@@ -377,6 +376,7 @@ typedef struct {
nsIURI *original_uri;
char *content_type;
char *charset;
PRUint32 response_status;
} nsChannel;
typedef struct {
@@ -466,6 +466,7 @@ typedef struct {
#define NSCHANNEL(x) ((nsIChannel*) &(x)->lpHttpChannelVtbl)
#define NSHTTPCHANNEL(x) ((nsIHttpChannel*) &(x)->lpHttpChannelVtbl)
#define NSUPCHANNEL(x) ((nsIUploadChannel*) &(x)->lpUploadChannelVtbl)
#define NSHTTPINTERNAL(x) ((nsIHttpChannelInternal*) &(x)->lpIHttpChannelInternalVtbl)
#define HTTPNEG(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
@@ -559,9 +560,8 @@ void nsAString_SetData(nsAString*,const PRUnichar*);
PRUint32 nsAString_GetData(const nsAString*,const PRUnichar**);
void nsAString_Finish(nsAString*);
nsIInputStream *create_nsstream(const char*,PRInt32);
nsICommandParams *create_nscommand_params(void);
void nsnode_to_nsstring(nsIDOMNode*,nsAString*);
HRESULT nsnode_to_nsstring(nsIDOMNode*,nsAString*);
void get_editor_controller(NSContainer*);
void init_nsevents(NSContainer*);
void add_nsevent_listener(NSContainer*,LPCWSTR);
+16
View File
@@ -461,6 +461,22 @@ static void NSAPI nsDocumentObserver_BeginLoad(nsIDocumentObserver *iface, nsIDo
static void NSAPI nsDocumentObserver_EndLoad(nsIDocumentObserver *iface, nsIDocument *aDocument)
{
NSContainer *This = NSDOCOBS_THIS(iface);
task_t *task;
TRACE("\n");
task = heap_alloc(sizeof(task_t));
task->doc = This->doc;
task->task_id = TASK_PARSECOMPLETE;
task->next = NULL;
/*
* This should be done in the worker thread that parses HTML,
* but we don't have such thread (Gecko parses HTML for us).
*/
push_task(task);
}
static void NSAPI nsDocumentObserver_ContentStatesChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
+105 -43
View File
@@ -54,10 +54,12 @@ typedef struct {
typedef struct {
void (*destroy)(BSCallback*);
HRESULT (*init_bindinfo)(BSCallback*);
HRESULT (*start_binding)(BSCallback*);
HRESULT (*stop_binding)(BSCallback*,HRESULT);
HRESULT (*read_data)(BSCallback*,IStream*);
HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR);
HRESULT (*on_response)(BSCallback*,DWORD);
} BSCallbackVtbl;
struct BSCallback {
@@ -75,6 +77,7 @@ struct BSCallback {
ULONG post_data_len;
ULONG readed;
DWORD bindf;
BOOL bindinfo_ready;
IMoniker *mon;
IBinding *binding;
@@ -344,19 +347,23 @@ static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *ifac
HRESULT hresult, LPCWSTR szError)
{
BSCallback *This = STATUSCLB_THIS(iface);
HRESULT hres;
TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
/* NOTE: IE7 calls GetBindResult here */
hres = This->vtbl->stop_binding(This, hresult);
if(This->binding) {
IBinding_Release(This->binding);
This->binding = NULL;
}
list_remove(&This->entry);
This->doc = NULL;
return This->vtbl->stop_binding(This, hresult);
return hres;
}
static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
@@ -367,6 +374,16 @@ static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
if(!This->bindinfo_ready) {
HRESULT hres;
hres = This->vtbl->init_bindinfo(This);
if(FAILED(hres))
return hres;
This->bindinfo_ready = TRUE;
}
*grfBINDF = This->bindf;
size = pbindinfo->cbSize;
@@ -469,9 +486,11 @@ static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwR
LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
{
BSCallback *This = HTTPNEG_THIS(iface);
FIXME("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
return E_NOTIMPL;
return This->vtbl->on_response(This, dwResponseCode);
}
static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
@@ -744,6 +763,11 @@ static void BufferBSC_destroy(BSCallback *bsc)
heap_free(This);
}
static HRESULT BufferBSC_init_bindinfo(BSCallback *bsc)
{
return S_OK;
}
static HRESULT BufferBSC_start_binding(BSCallback *bsc)
{
return S_OK;
@@ -794,14 +818,21 @@ static HRESULT BufferBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR
return S_OK;
}
static HRESULT BufferBSC_on_response(BSCallback *bsc, DWORD response_code)
{
return S_OK;
}
#undef BUFFERBSC_THIS
static const BSCallbackVtbl BufferBSCVtbl = {
BufferBSC_destroy,
BufferBSC_init_bindinfo,
BufferBSC_start_binding,
BufferBSC_stop_binding,
BufferBSC_read_data,
BufferBSC_on_progress,
BufferBSC_on_response
};
@@ -848,14 +879,46 @@ struct nsChannelBSC {
nsProtocolStream *nsstream;
};
static void on_start_nsrequest(nsChannelBSC *This)
{
nsresult nsres;
/* FIXME: it's needed for http connections from BindToObject. */
if(!This->nschannel->response_status)
This->nschannel->response_status = 200;
nsres = nsIStreamListener_OnStartRequest(This->nslistener,
(nsIRequest*)NSCHANNEL(This->nschannel), This->nscontext);
if(NS_FAILED(nsres))
FIXME("OnStartRequest failed: %08x\n", nsres);
}
static void on_stop_nsrequest(nsChannelBSC *This)
{
nsresult nsres;
if(!This->nslistener)
return;
if(!This->bsc.readed) {
TRACE("No data read! Calling OnStartRequest\n");
on_start_nsrequest(This);
}
nsres = nsIStreamListener_OnStopRequest(This->nslistener, (nsIRequest*)NSCHANNEL(This->nschannel),
This->nscontext, NS_OK);
if(NS_FAILED(nsres))
WARN("OnStopRequest failed: %08x\n", nsres);
}
static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
{
DWORD read;
nsresult nsres;
HRESULT hres;
if(!This->nslistener) {
BYTE buf[1024];
DWORD read;
do {
read = 0;
@@ -869,21 +932,21 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
This->nsstream = create_nsprotocol_stream();
do {
hres = IStream_Read(stream, This->nsstream->buf, sizeof(This->nsstream->buf),
&This->nsstream->buf_size);
if(!This->nsstream->buf_size)
read = 0;
hres = IStream_Read(stream, This->nsstream->buf+This->nsstream->buf_size,
sizeof(This->nsstream->buf)-This->nsstream->buf_size, &read);
if(!read)
break;
if(!This->bsc.readed && This->nsstream->buf_size >= 2 && *(WORD*)This->nsstream->buf == 0xfeff) {
This->nschannel->charset = heap_alloc(sizeof(UTF16_STR));
memcpy(This->nschannel->charset, UTF16_STR, sizeof(UTF16_STR));
}
This->nsstream->buf_size += read;
if(!This->bsc.readed) {
nsres = nsIStreamListener_OnStartRequest(This->nslistener,
(nsIRequest*)NSCHANNEL(This->nschannel), This->nscontext);
if(NS_FAILED(nsres))
FIXME("OnStartRequest failed: %08x\n", nsres);
if(This->nsstream->buf_size >= 2
&& (BYTE)This->nsstream->buf[0] == 0xff
&& (BYTE)This->nsstream->buf[1] == 0xfe)
This->nschannel->charset = heap_strdupA(UTF16_STR);
on_start_nsrequest(This);
/* events are reset when a new document URI is loaded, so re-initialise them here */
if(This->bsc.doc && This->bsc.doc->bscallback == This && This->bsc.doc->nscontainer) {
@@ -901,22 +964,15 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
if(NS_FAILED(nsres))
ERR("OnDataAvailable failed: %08x\n", nsres);
if(This->nsstream->buf_size)
FIXME("buffer is not empty!\n");
if(This->nsstream->buf_size == sizeof(This->nsstream->buf)) {
ERR("buffer is full\n");
break;
}
}while(hres == S_OK);
return S_OK;
}
static void on_stop_nsrequest(nsChannelBSC *This)
{
if(!This->nslistener)
return;
nsIStreamListener_OnStopRequest(This->nslistener, (nsIRequest*)NSCHANNEL(This->nschannel),
This->nscontext, NS_OK);
}
static void add_nsrequest(nsChannelBSC *This)
{
nsresult nsres;
@@ -957,6 +1013,19 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc)
return S_OK;
}
static HRESULT nsChannelBSC_init_bindinfo(BSCallback *bsc)
{
nsChannelBSC *This = NSCHANNELBSC_THIS(bsc);
if(This->nschannel && This->nschannel->post_data_stream) {
parse_post_data(This->nschannel->post_data_stream, &This->bsc.headers, &This->bsc.post_data, &This->bsc.post_data_len);
TRACE("headers = %s post_data = %s\n", debugstr_w(This->bsc.headers),
debugstr_an(This->bsc.post_data, This->bsc.post_data_len));
}
return S_OK;
}
static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result)
{
nsChannelBSC *This = NSCHANNELBSC_THIS(bsc);
@@ -974,23 +1043,6 @@ static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result)
}
}
if(FAILED(result))
return S_OK;
if(This->bsc.doc && This->bsc.doc->bscallback == This && !This->bsc.doc->nscontainer) {
task_t *task = heap_alloc(sizeof(task_t));
task->doc = This->bsc.doc;
task->task_id = TASK_PARSECOMPLETE;
task->next = NULL;
/*
* This should be done in the worker thread that parses HTML,
* but we don't have such thread.
*/
push_task(task);
}
return S_OK;
}
@@ -1017,14 +1069,24 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW
return S_OK;
}
static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code)
{
nsChannelBSC *This = NSCHANNELBSC_THIS(bsc);
This->nschannel->response_status = response_code;
return S_OK;
}
#undef NSCHANNELBSC_THIS
static const BSCallbackVtbl nsChannelBSCVtbl = {
nsChannelBSC_destroy,
nsChannelBSC_init_bindinfo,
nsChannelBSC_start_binding,
nsChannelBSC_stop_binding,
nsChannelBSC_read_data,
nsChannelBSC_on_progress,
nsChannelBSC_on_response
};
nsChannelBSC *create_channelbsc(IMoniker *mon)
+83 -72
View File
@@ -38,14 +38,10 @@ WINE_DECLARE_DEBUG_CHANNEL(gecko);
#define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
#define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
#define NS_PROFILE_CONTRACTID "@mozilla.org/profile/manager;1"
#define NS_MEMORY_CONTRACTID "@mozilla.org/xpcom/memory-service;1"
#define NS_STRINGSTREAM_CONTRACTID "@mozilla.org/io/string-input-stream;1"
#define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
#define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html"
#define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1"
#define NS_ARRAY_CONTRACTID "@mozilla.org/array;1"
#define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1"
#define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1"
#define APPSTARTUP_TOPIC "app-startup"
@@ -296,12 +292,38 @@ static BOOL load_wine_gecko(PRUnichar *gre_path)
return ret;
}
static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
{
nsresult nsres;
nsres = nsIPrefBranch_SetBoolPref(pref, pref_name, val);
if(NS_FAILED(nsres))
ERR("Could not set pref %s\n", debugstr_a(pref_name));
}
static void set_int_pref(nsIPrefBranch *pref, const char *pref_name, int val)
{
nsresult nsres;
nsres = nsIPrefBranch_SetIntPref(pref, pref_name, val);
if(NS_FAILED(nsres))
ERR("Could not set pref %s\n", debugstr_a(pref_name));
}
static void set_string_pref(nsIPrefBranch *pref, const char *pref_name, const char *val)
{
nsresult nsres;
nsres = nsIPrefBranch_SetCharPref(pref, pref_name, val);
if(NS_FAILED(nsres))
ERR("Could not set pref %s\n", debugstr_a(pref_name));
}
static void set_lang(nsIPrefBranch *pref)
{
char langs[100];
DWORD res, size, type;
HKEY hkey;
nsresult nsres;
static const WCHAR international_keyW[] =
{'S','o','f','t','w','a','r','e',
@@ -321,9 +343,7 @@ static void set_lang(nsIPrefBranch *pref)
TRACE("Setting lang %s\n", debugstr_a(langs));
nsres = nsIPrefBranch_SetCharPref(pref, "intl.accept_languages", langs);
if(NS_FAILED(nsres))
ERR("SetCharPref failed: %08x\n", nsres);
set_string_pref(pref, "intl.accept_languages", langs);
}
static void set_proxy(nsIPrefBranch *pref)
@@ -333,7 +353,6 @@ static void set_proxy(nsIPrefBranch *pref)
int proxy_port_num;
DWORD enabled = 0, res, size, type;
HKEY hkey;
nsresult nsres;
static const WCHAR proxy_keyW[] =
{'S','o','f','t','w','a','r','e',
@@ -368,30 +387,12 @@ static void set_proxy(nsIPrefBranch *pref)
proxy_port_num = atoi(proxy_port + 1);
TRACE("Setting proxy to %s, port %d\n", debugstr_a(proxy), proxy_port_num);
nsres = nsIPrefBranch_SetIntPref(pref, "network.proxy.type", 1);
if(NS_FAILED(nsres))
ERR("SetIntPref network.proxy.type failed: %08x\n", nsres);
nsres = nsIPrefBranch_SetCharPref(pref, "network.proxy.http", proxy);
if(NS_FAILED(nsres))
ERR("SetCharPref network.proxy.http failed: %08x\n", nsres);
nsres = nsIPrefBranch_SetIntPref(pref, "network.proxy.http_port", proxy_port_num);
if(NS_FAILED(nsres))
ERR("SetIntPref network.proxy.http_port failed: %08x\n", nsres);
nsres = nsIPrefBranch_SetCharPref(pref, "network.proxy.ssl", proxy);
if(NS_FAILED(nsres))
ERR("SetCharPref network.proxy.ssl failed: %08x\n", nsres);
nsres = nsIPrefBranch_SetIntPref(pref, "network.proxy.ssl_port", proxy_port_num);
if(NS_FAILED(nsres))
ERR("SetIntPref network.proxy.ssl_port failed: %08x\n", nsres);
}
set_string_pref(pref, "network.proxy.http", proxy);
set_string_pref(pref, "network.proxy.ssl", proxy);
static void set_bool_pref(nsIPrefBranch *pref, const char *pref_name, BOOL val)
{
nsresult nsres;
nsres = nsIPrefBranch_SetBoolPref(pref, pref_name, val);
if(NS_FAILED(nsres))
ERR("Could not set pref %s\n", debugstr_a(pref_name));
set_int_pref(pref, "network.proxy.type", 1);
set_int_pref(pref, "network.proxy.http_port", proxy_port_num);
set_int_pref(pref, "network.proxy.ssl_port", proxy_port_num);
}
static void set_preferences(void)
@@ -410,6 +411,7 @@ static void set_preferences(void)
set_proxy(pref);
set_bool_pref(pref, "security.warn_entering_secure", FALSE);
set_bool_pref(pref, "security.warn_submit_insecure", FALSE);
set_int_pref(pref, "layout.spellcheckDefault", 0);
nsIPrefBranch_Release(pref);
}
@@ -575,32 +577,6 @@ void nsAString_Finish(nsAString *str)
NS_StringContainerFinish(str);
}
nsIInputStream *create_nsstream(const char *data, PRInt32 data_len)
{
nsIStringInputStream *ret;
nsresult nsres;
if(!pCompMgr)
return NULL;
nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
NS_STRINGSTREAM_CONTRACTID, NULL, &IID_nsIStringInputStream,
(void**)&ret);
if(NS_FAILED(nsres)) {
ERR("Could not get nsIStringInputStream\n");
return NULL;
}
nsres = nsIStringInputStream_SetData(ret, data, data_len);
if(NS_FAILED(nsres)) {
ERR("AdoptData failed: %08x\n", nsres);
nsIStringInputStream_Release(ret);
return NULL;
}
return (nsIInputStream*)ret;
}
nsICommandParams *create_nscommand_params(void)
{
nsICommandParams *ret = NULL;
@@ -633,7 +609,7 @@ nsresult get_nsinterface(nsISupports *iface, REFIID riid, void **ppv)
return nsres;
}
static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
static HRESULT nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode *nsnode, nsAString *str)
{
nsIDOMNodeList *node_list = NULL;
PRBool has_children = FALSE;
@@ -645,7 +621,7 @@ static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode
nsres = nsIDOMNode_GetNodeType(nsnode, &type);
if(NS_FAILED(nsres)) {
ERR("GetType failed: %08x\n", nsres);
return;
return E_FAIL;
}
switch(type) {
@@ -676,6 +652,9 @@ static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode
nsIDOMDocument_Release(nsdoc);
break;
}
case DOCUMENT_TYPE_NODE:
WARN("Ignoring DOCUMENT_TYPE_NODE\n");
break;
case DOCUMENT_FRAGMENT_NODE:
break;
default:
@@ -708,35 +687,37 @@ static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode
nsIContentSerializer_AppendElementEnd(serializer, nselem, str);
nsIDOMElement_Release(nselem);
}
return S_OK;
}
void nsnode_to_nsstring(nsIDOMNode *nsdoc, nsAString *str)
HRESULT nsnode_to_nsstring(nsIDOMNode *nsnode, nsAString *str)
{
nsIContentSerializer *serializer;
nsIDOMNode *nsnode;
nsresult nsres;
HRESULT hres;
nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr,
NS_HTMLSERIALIZER_CONTRACTID, NULL, &IID_nsIContentSerializer,
(void**)&serializer);
if(NS_FAILED(nsres)) {
ERR("Could not get nsIContentSerializer: %08x\n", nsres);
return;
return E_FAIL;
}
nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE, FALSE /* FIXME */);
if(NS_FAILED(nsres))
ERR("Init failed: %08x\n", nsres);
nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMNode, (void**)&nsnode);
nsnode_to_nsstring_rec(serializer, nsnode, str);
nsIDOMNode_Release(nsnode);
nsres = nsIContentSerializer_Flush(serializer, str);
if(NS_FAILED(nsres))
ERR("Flush failed: %08x\n", nsres);
hres = nsnode_to_nsstring_rec(serializer, nsnode, str);
if(SUCCEEDED(hres)) {
nsres = nsIContentSerializer_Flush(serializer, str);
if(NS_FAILED(nsres))
ERR("Flush failed: %08x\n", nsres);
}
nsIContentSerializer_Release(serializer);
return hres;
}
void get_editor_controller(NSContainer *This)
@@ -1179,6 +1160,33 @@ static nsrefcnt NSAPI nsURIContentListener_Release(nsIURIContentListener *iface)
return nsIWebBrowserChrome_Release(NSWBCHROME(This));
}
static BOOL translate_url(HTMLDocument *doc, nsIWineURI *nsuri)
{
OLECHAR *new_url = NULL, *url;
BOOL ret = FALSE;
LPCWSTR wine_url;
HRESULT hres;
if(!doc->hostui)
return FALSE;
nsIWineURI_GetWineURL(nsuri, &wine_url);
url = heap_strdupW(wine_url);
hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
heap_free(url);
if(hres != S_OK || !new_url)
return FALSE;
if(strcmpW(url, new_url)) {
FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
ret = TRUE;
}
CoTaskMemFree(new_url);
return ret;
}
static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener *iface,
nsIURI *aURI, PRBool *_retval)
{
@@ -1222,12 +1230,15 @@ static nsresult NSAPI nsURIContentListener_OnStartURIOpen(nsIURIContentListener
IMoniker_Release(mon);
}
*_retval = FALSE;
}else if(This->doc) {
*_retval = translate_url(This->doc, wine_uri);
}
nsIWineURI_Release(wine_uri);
*_retval = FALSE;
return This->content_listener
return !*_retval && This->content_listener
? nsIURIContentListener_OnStartURIOpen(This->content_listener, aURI, _retval)
: NS_OK;
}
-13
View File
@@ -131,7 +131,6 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
{
NSContainer *This = NSEVENTLIST_THIS(iface)->This;
nsIDOMHTMLElement *nsbody = NULL;
task_t *task;
TRACE("(%p)\n", This);
@@ -149,18 +148,6 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
if(This->doc->usermode == EDITMODE)
handle_edit_load(This->doc);
task = heap_alloc(sizeof(task_t));
task->doc = This->doc;
task->task_id = TASK_PARSECOMPLETE;
task->next = NULL;
/*
* This should be done in the worker thread that parses HTML,
* but we don't have such thread (Gecko parses HTML for us).
*/
push_task(task);
if(!This->doc->nsdoc) {
ERR("NULL nsdoc\n");
return NS_ERROR_FAILURE;
+47 -14
View File
@@ -284,19 +284,6 @@ interface nsIInputStream : nsISupports
nsresult IsNonBlocking(PRBool *_retval);
}
[
object,
uuid(450cd2d4-f0fd-424d-b365-b1251f80fd53),
local
/* NOT_FROZEN */
]
interface nsIStringInputStream : nsIInputStream
{
nsresult SetData(const char *data, PRInt32 dataLen);
nsresult AdoptData(char *data, PRInt32 dataLen);
nsresult ShareData(const char *data, PRInt32 dataLen);
}
[
object,
uuid(07a22cc0-0ce5-11d3-9331-00104ba0fd40),
@@ -333,6 +320,34 @@ interface nsIURI : nsISupports
nsresult GetOriginCharset(nsACString *aOriginCharset);
}
[
object,
uuid(d6116970-8034-11d3-9399-00104ba0fd40),
local
/* FROZEN */
]
interface nsIURL : nsIURI
{
nsresult GetFilePath(nsACString *aFilePath);
nsresult SetFilePath(const nsACString *aFilePath);
nsresult GetParam(nsACString *aParam);
nsresult SetParam(const nsACString *aParam);
nsresult GetQuery(nsACString *aQuery);
nsresult SetQuery(const nsACString *aQuery);
nsresult GetRef(nsACString *aRef);
nsresult SetRef(const nsACString *aRef);
nsresult GetDirectory(nsACString *aDirectory);
nsresult SetDirectory(const nsACString *aDirectory);
nsresult GetFileName(nsACString *aFileName);
nsresult SetFileName(const nsACString *aFileName);
nsresult GetFileBaseName(nsACString *aFileBaseName);
nsresult SetFileBaseName(const nsACString *aFileBaseName);
nsresult GetFileExtension(nsACString *aFileExtension);
nsresult SetFileExtension(const nsACString *aFileExtension);
nsresult GetCommonBaseSpec(nsIURI *aURIToCompare, nsACString *_retval);
nsresult GetRelativeSpec(nsIURI *aURIToCompare, nsACString *_retval);
}
[
object,
uuid(ef6bfbd2-fd46-48d8-96b7-9f8f0fd387fe),
@@ -452,6 +467,24 @@ interface nsIHttpChannel : nsIChannel
nsresult IsNoCacheResponse(PRBool *_retval);
}
[
object,
uuid(0eb66361-faaa-4e52-8c7e-6c25f11f8e3c),
local
/* NOT_FROZEN */
]
interface nsIHttpChannelInternal : nsISupports
{
nsresult GetDocumentURI(nsIURI **aDocumentURI);
nsresult SetDocumentURI(nsIURI *aDocumentURI);
nsresult GetRequestVersion(PRUint32 *major, PRUint32 *minor);
nsresult GetResponseVersion(PRUint32 *major, PRUint32 *minor);
nsresult SetCookie(const char *aCookieHeader);
nsresult SetupFallbackChannel(const char *aFallbackKey);
nsresult GetForceAllowThirdPartyCookie(PRBool *aForceAllowThirdPartyCookie);
nsresult SetForceAllowThirdPartyCookie(PRBool aForceAllowThirdPartyCookie);
}
[
object,
uuid(ddf633d8-e9a4-439d-ad88-de636fd9bb75),
@@ -2547,7 +2580,7 @@ interface nsIDocumentObserver : nsIMutationObserver
local
/* INTERNAL */
]
interface nsIWineURI : nsIURI
interface nsIWineURI : nsIURL
{
typedef struct NSContainer NSContainer;
+465 -65
View File
@@ -57,6 +57,7 @@ typedef struct {
LONG ref;
nsIURI *uri;
nsIURL *nsurl;
NSContainer *container;
LPWSTR wine_url;
PRBool is_doc_uri;
@@ -68,6 +69,14 @@ typedef struct {
static nsresult create_uri(nsIURI*,NSContainer*,nsIWineURI**);
static const char *debugstr_nsacstr(const nsACString *nsstr)
{
const char *data;
nsACString_GetData(nsstr, &data);
return debugstr_a(data);
}
HRESULT nsuri_to_url(LPCWSTR nsuri, BSTR *ret)
{
const WCHAR *ptr = nsuri;
@@ -167,8 +176,6 @@ static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef r
{
nsChannel *This = NSCHANNEL_THIS(iface);
*result = NULL;
if(IsEqualGUID(&IID_nsISupports, riid)) {
TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
*result = NSCHANNEL(This);
@@ -178,12 +185,18 @@ static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef r
}else if(IsEqualGUID(&IID_nsIChannel, riid)) {
TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
*result = NSCHANNEL(This);
}else if(This->http_channel && IsEqualGUID(&IID_nsIHttpChannel, riid)) {
}else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
*result = NSHTTPCHANNEL(This);
*result = This->http_channel ? NSHTTPCHANNEL(This) : NULL;
}else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
*result = NSUPCHANNEL(This);
}else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
*result = This->http_channel_internal ? NSHTTPINTERNAL(This) : NULL;
}else {
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
*result = NULL;
}
if(*result) {
@@ -191,10 +204,6 @@ static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef r
return NS_OK;
}
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
if(This->channel)
return nsIChannel_QueryInterface(This->channel, riid, result);
return NS_NOINTERFACE;
}
@@ -219,6 +228,8 @@ static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
nsIChannel_Release(This->channel);
if(This->http_channel)
nsIHttpChannel_Release(This->http_channel);
if(This->http_channel_internal)
nsIHttpChannel_Release(This->http_channel_internal);
if(This->owner)
nsISupports_Release(This->owner);
if(This->post_data_stream)
@@ -606,37 +617,6 @@ static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_re
return NS_ERROR_NOT_IMPLEMENTED;
}
static BOOL do_load_from_moniker_hack(nsChannel *This)
{
nsACString scheme_str;
nsresult nsres;
BOOL ret = TRUE;
/*
* We should always load the page from IMoniker, but Wine is not yet
* ready for this. This function is a heuristic, that decides which
* way of loading is better (Gecko implementation or IMoniker). The
* aim is to always return TRUE.
*/
/* Load from moniker if there is no Gecko channel available */
if(!This->channel)
return TRUE;
nsACString_Init(&scheme_str, NULL);
nsres = nsIWineURI_GetScheme(This->uri, &scheme_str);
if(NS_SUCCEEDED(nsres)) {
const char *scheme;
nsACString_GetData(&scheme_str, &scheme);
ret = !strcmp(scheme, "wine") || !strcmp(scheme, "about");
}
nsACString_Finish(&scheme_str);
return ret;
}
static HRESULT create_mon_for_nschannel(nsChannel *channel, IMoniker **mon)
{
nsIWineURI *wine_uri;
@@ -730,8 +710,7 @@ static nsresult async_open_doc_uri(nsChannel *This, NSContainer *container,
This->content_type = heap_strdupWtoA(container->doc->mime);
}
if(do_load_from_moniker_hack(This))
return WINE_NS_LOAD_FROM_MONIKER;
return NS_OK;
}else {
BOOL cont = before_async_open(This, container);
@@ -762,23 +741,9 @@ static nsresult async_open(nsChannel *This, NSContainer *container, nsIStreamLis
{
nsChannelBSC *bscallback;
IMoniker *mon = NULL;
nsresult nsres;
task_t *task;
HRESULT hres;
if(This->channel) {
nsres = nsIChannel_AsyncOpen(This->channel, listener, context);
if(mon)
IMoniker_Release(mon);
if(NS_FAILED(nsres) && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI))
return WINE_NS_LOAD_FROM_MONIKER;
return nsres;
}
TRACE("channel == NULL\n");
hres = create_mon_for_nschannel(This, &mon);
if(FAILED(hres))
return NS_ERROR_UNEXPECTED;
@@ -980,10 +945,15 @@ static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, PRUint3
TRACE("(%p)->(%p)\n", This, aResponseStatus);
if(This->response_status) {
*aResponseStatus = This->response_status;
return NS_OK;
}
if(This->http_channel)
return nsIHttpChannel_GetResponseStatus(This->http_channel, aResponseStatus);
return NS_ERROR_NOT_IMPLEMENTED;
return NS_ERROR_UNEXPECTED;
}
static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
@@ -1217,6 +1187,131 @@ static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
nsUploadChannel_GetUploadStream
};
#define NSHTTPINTERNAL_THIS(iface) DEFINE_THIS(nsChannel, IHttpChannelInternal, iface)
static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
nsQIResult result)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
return nsIChannel_QueryInterface(NSCHANNEL(This), riid, result);
}
static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
return nsIChannel_AddRef(NSCHANNEL(This));
}
static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
return nsIChannel_Release(NSCHANNEL(This));
}
static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_GetDocumentURI(This->http_channel_internal, aDocumentURI);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_SetDocumentURI(This->http_channel_internal, aDocumentURI);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_GetRequestVersion(This->http_channel_internal, major, minor);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_GetResponseVersion(This->http_channel_internal, major, minor);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_SetCookie(This->http_channel_internal, aCookieHeader);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_SetupFallbackChannel(This->http_channel_internal, aFallbackKey);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool *aForceThirdPartyCookie)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_GetForceAllowThirdPartyCookie(This->http_channel_internal, aForceThirdPartyCookie);
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool aForceThirdPartyCookie)
{
nsChannel *This = NSHTTPINTERNAL_THIS(iface);
TRACE("(%p)->()\n", This);
if(This->http_channel_internal)
return nsIHttpChannelInternal_SetForceAllowThirdPartyCookie(This->http_channel_internal, aForceThirdPartyCookie);
return NS_ERROR_NOT_IMPLEMENTED;
}
#undef NSHTTPINTERNAL_THIS
static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
nsHttpChannelInternal_QueryInterface,
nsHttpChannelInternal_AddRef,
nsHttpChannelInternal_Release,
nsHttpChannelInternal_GetDocumentURI,
nsHttpChannelInternal_SetDocumentURI,
nsHttpChannelInternal_GetRequestVersion,
nsHttpChannelInternal_GetResponseVersion,
nsHttpChannelInternal_SetCookie,
nsHttpChannelInternal_SetupFallbackChannel,
nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
nsHttpChannelInternal_SetForceAllowThirdPartyCookie
};
#define NSURI_THIS(iface) DEFINE_THIS(nsURI, WineURI, iface)
static nsresult NSAPI nsURI_QueryInterface(nsIWineURI *iface, nsIIDRef riid, nsQIResult result)
@@ -1231,6 +1326,9 @@ static nsresult NSAPI nsURI_QueryInterface(nsIWineURI *iface, nsIIDRef riid, nsQ
}else if(IsEqualGUID(&IID_nsIURI, riid)) {
TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
*result = NSURI(This);
}else if(IsEqualGUID(&IID_nsIURL, riid)) {
TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
*result = NSURI(This);
}else if(IsEqualGUID(&IID_nsIWineURI, riid)) {
TRACE("(%p)->(IID_nsIWineURI %p)\n", This, result);
*result = NSURI(This);
@@ -1265,6 +1363,8 @@ static nsrefcnt NSAPI nsURI_Release(nsIWineURI *iface)
if(!ref) {
if(This->container)
nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
if(This->nsurl)
nsIURL_Release(This->nsurl);
if(This->uri)
nsIURI_Release(This->uri);
heap_free(This->wine_url);
@@ -1688,6 +1788,280 @@ static nsresult NSAPI nsURI_GetOriginCharset(nsIWineURI *iface, nsACString *aOri
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetFilePath(nsIWineURI *iface, nsACString *aFilePath)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aFilePath);
if(This->nsurl)
return nsIURL_GetFilePath(This->nsurl, aFilePath);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetFilePath(nsIWineURI *iface, const nsACString *aFilePath)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
if(This->nsurl)
return nsIURL_SetFilePath(This->nsurl, aFilePath);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetParam(nsIWineURI *iface, nsACString *aParam)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aParam);
if(This->nsurl)
return nsIURL_GetParam(This->nsurl, aParam);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetParam(nsIWineURI *iface, const nsACString *aParam)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aParam));
if(This->nsurl)
return nsIURL_SetParam(This->nsurl, aParam);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetQuery(nsIWineURI *iface, nsACString *aQuery)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aQuery);
if(This->nsurl)
return nsIURL_GetQuery(This->nsurl, aQuery);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetQuery(nsIWineURI *iface, const nsACString *aQuery)
{
nsURI *This = NSURI_THIS(iface);
const WCHAR *ptr1, *ptr2;
const char *query;
WCHAR *new_url, *ptr;
DWORD len, size;
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
if(This->nsurl)
nsIURL_SetQuery(This->nsurl, aQuery);
if(!This->wine_url)
return NS_OK;
nsACString_GetData(aQuery, &query);
size = len = MultiByteToWideChar(CP_ACP, 0, query, -1, NULL, 0);
ptr1 = strchrW(This->wine_url, '?');
if(ptr1) {
size += ptr1-This->wine_url;
ptr2 = strchrW(ptr1, '#');
if(ptr2)
size += strlenW(ptr2);
}else {
ptr1 = This->wine_url + strlenW(This->wine_url);
ptr2 = NULL;
size += strlenW(This->wine_url);
}
if(*query)
size++;
new_url = heap_alloc(size*sizeof(WCHAR));
memcpy(new_url, This->wine_url, (ptr1-This->wine_url)*sizeof(WCHAR));
ptr = new_url + (ptr1-This->wine_url);
if(*query) {
*ptr++ = '?';
MultiByteToWideChar(CP_ACP, 0, query, -1, ptr, len);
ptr += len-1;
}
if(ptr2)
strcpyW(ptr, ptr2);
else
*ptr = 0;
TRACE("setting %s\n", debugstr_w(new_url));
heap_free(This->wine_url);
This->wine_url = new_url;
return NS_OK;
}
static nsresult NSAPI nsURL_GetRef(nsIWineURI *iface, nsACString *aRef)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aRef);
if(This->nsurl)
return nsIURL_GetRef(This->nsurl, aRef);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetRef(nsIWineURI *iface, const nsACString *aRef)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
if(This->nsurl)
return nsIURL_SetRef(This->nsurl, aRef);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetDirectory(nsIWineURI *iface, nsACString *aDirectory)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aDirectory);
if(This->nsurl)
return nsIURL_GetDirectory(This->nsurl, aDirectory);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetDirectory(nsIWineURI *iface, const nsACString *aDirectory)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
if(This->nsurl)
return nsIURL_SetDirectory(This->nsurl, aDirectory);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetFileName(nsIWineURI *iface, nsACString *aFileName)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aFileName);
if(This->nsurl)
return nsIURL_GetFileName(This->nsurl, aFileName);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetFileName(nsIWineURI *iface, const nsACString *aFileName)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
if(This->nsurl)
return nsIURL_SetFileName(This->nsurl, aFileName);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetFileBaseName(nsIWineURI *iface, nsACString *aFileBaseName)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aFileBaseName);
if(This->nsurl)
return nsIURL_GetFileBaseName(This->nsurl, aFileBaseName);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetFileBaseName(nsIWineURI *iface, const nsACString *aFileBaseName)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
if(This->nsurl)
return nsIURL_SetFileBaseName(This->nsurl, aFileBaseName);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetFileExtension(nsIWineURI *iface, nsACString *aFileExtension)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p)\n", This, aFileExtension);
if(This->nsurl)
return nsIURL_GetFileExtension(This->nsurl, aFileExtension);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_SetFileExtension(nsIWineURI *iface, const nsACString *aFileExtension)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
if(This->nsurl)
return nsIURL_SetFileExtension(This->nsurl, aFileExtension);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIWineURI *iface, nsIURI *aURIToCompare, nsACString *_retval)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
if(This->nsurl)
return nsIURL_GetCommonBaseSpec(This->nsurl, aURIToCompare, _retval);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURL_GetRelativeSpec(nsIWineURI *iface, nsIURI *aURIToCompare, nsACString *_retval)
{
nsURI *This = NSURI_THIS(iface);
TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
if(This->nsurl)
return nsIURL_GetRelativeSpec(This->nsurl, aURIToCompare, _retval);
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult NSAPI nsURI_GetNSContainer(nsIWineURI *iface, NSContainer **aContainer)
{
nsURI *This = NSURI_THIS(iface);
@@ -1813,6 +2187,24 @@ static const nsIWineURIVtbl nsWineURIVtbl = {
nsURI_GetAsciiSpec,
nsURI_GetAsciiHost,
nsURI_GetOriginCharset,
nsURL_GetFilePath,
nsURL_SetFilePath,
nsURL_GetParam,
nsURL_SetParam,
nsURL_GetQuery,
nsURL_SetQuery,
nsURL_GetRef,
nsURL_SetRef,
nsURL_GetDirectory,
nsURL_SetDirectory,
nsURL_GetFileName,
nsURL_SetFileName,
nsURL_GetFileBaseName,
nsURL_SetFileBaseName,
nsURL_GetFileExtension,
nsURL_SetFileExtension,
nsURL_GetCommonBaseSpec,
nsURL_GetRelativeSpec,
nsURI_GetNSContainer,
nsURI_SetNSContainer,
nsURI_GetIsDocumentURI,
@@ -1836,6 +2228,11 @@ static nsresult create_uri(nsIURI *uri, NSContainer *container, nsIWineURI **_re
if(container)
nsIWebBrowserChrome_AddRef(NSWBCHROME(container));
if(uri)
nsIURI_QueryInterface(uri, &IID_nsIURL, (void**)&ret->nsurl);
else
ret->nsurl = NULL;
TRACE("retval=%p\n", ret);
*_retval = NSWINEURI(ret);
return NS_OK;
@@ -2051,15 +2448,15 @@ static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const ch
static BOOL is_gecko_special_uri(const char *spec)
{
static const char chromeW[] = "chrome:";
static const char jarW[] = "jar:";
static const char resourceW[] = "resource:";
static const char javascriptW[] = "javascript:";
static const char *special_schemes[] = {"chrome:", "jar:", "resource:", "javascript:", "wyciwyg:"};
int i;
return !strncasecmp(spec, chromeW, sizeof(chromeW)-1)
|| !strncasecmp(spec, resourceW, sizeof(resourceW)-1)
|| !strncasecmp(spec, jarW, sizeof(jarW)-1)
|| !strncasecmp(spec, javascriptW, sizeof(javascriptW)-1);
for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
return TRUE;
}
return FALSE;
}
static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec,
@@ -2187,6 +2584,7 @@ static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI
ret->lpHttpChannelVtbl = &nsChannelVtbl;
ret->lpUploadChannelVtbl = &nsUploadChannelVtbl;
ret->lpIHttpChannelInternalVtbl = &nsHttpChannelInternalVtbl;
ret->ref = 1;
ret->channel = channel;
ret->uri = wine_uri;
@@ -2194,8 +2592,10 @@ static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI
nsIURI_AddRef(aURI);
ret->original_uri = aURI;
if(channel)
if(channel) {
nsIChannel_QueryInterface(channel, &IID_nsIHttpChannel, (void**)&ret->http_channel);
nsIChannel_QueryInterface(channel, &IID_nsIHttpChannelInternal, (void**)&ret->http_channel_internal);
}
*_retval = NSCHANNEL(ret);
return NS_OK;
+44 -7
View File
@@ -84,8 +84,10 @@ static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
if(!ref) {
release_dispex(&This->dispex);
heap_free(This);
}
return ref;
}
@@ -139,8 +141,19 @@ static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p)
static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p)
{
OmNavigator *This = OMNAVIGATOR_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
static const WCHAR app_nameW[] =
{'M','i','c','r','o','s','o','f','t',' ',
'I','n','t','e','r','n','e','t',' ',
'E','x','p','l','o','r','e','r',0};
TRACE("(%p)->(%p)\n", This, p);
*p = SysAllocString(app_nameW);
if(!*p)
return E_OUTOFMEMORY;
return S_OK;
}
static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
@@ -166,8 +179,24 @@ static HRESULT WINAPI OmNavigator_get_appVersion(IOmNavigator *iface, BSTR *p)
static HRESULT WINAPI OmNavigator_get_userAgent(IOmNavigator *iface, BSTR *p)
{
OmNavigator *This = OMNAVIGATOR_THIS(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
char user_agent[512];
DWORD size;
HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
size = sizeof(user_agent);
hres = ObtainUserAgentString(0, user_agent, &size);
if(FAILED(hres))
return hres;
size = MultiByteToWideChar(CP_ACP, 0, user_agent, -1, NULL, 0);
*p = SysAllocStringLen(NULL, size-1);
if(!*p)
return E_OUTOFMEMORY;
MultiByteToWideChar(CP_ACP, 0, user_agent, -1, *p, size);
return S_OK;
}
static HRESULT WINAPI OmNavigator_javaEnabled(IOmNavigator *iface, VARIANT_BOOL *enabled)
@@ -215,8 +244,16 @@ static HRESULT WINAPI OmNavigator_get_opsProfile(IOmNavigator *iface, IHTMLOpsPr
static HRESULT WINAPI OmNavigator_toString(IOmNavigator *iface, BSTR *String)
{
OmNavigator *This = OMNAVIGATOR_THIS(iface);
FIXME("(%p)->(%p)\n", This, String);
return E_NOTIMPL;
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
TRACE("(%p)->(%p)\n", This, String);
if(!String)
return E_INVALIDARG;
*String = SysAllocString(objectW);
return *String ? S_OK : E_OUTOFMEMORY;
}
static HRESULT WINAPI OmNavigator_get_cpuClass(IOmNavigator *iface, BSTR *p)
+12 -149
View File
@@ -39,129 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define USER_AGENT "User-Agent:"
#define CONTENT_TYPE "Content-Type:"
static int fix_headers(char *buf, DWORD post_len)
{
char *ptr = buf, *ptr2;
while(*ptr && (ptr[0] != '\r' || ptr[1] != '\n')) {
for(ptr2=ptr+1; *ptr2 && (ptr2[0] != '\r' || ptr2[1] != '\n'); ptr2++);
if(*ptr2)
ptr2 += 2;
if(!strncasecmp(ptr, USER_AGENT, sizeof(USER_AGENT)-1)) {
FIXME("Ignoring User-Agent header\n");
memmove(ptr, ptr2, strlen(ptr2)+1);
}else if(!post_len && !strncasecmp(ptr, CONTENT_TYPE, sizeof(CONTENT_TYPE)-1)) {
TRACE("Ignoring Content-Type header\n");
memmove(ptr, ptr2, strlen(ptr2)+1);
}else {
ptr = ptr2;
}
}
*ptr = 0;
return ptr-buf;
}
static nsIInputStream *get_post_data_stream(IBindCtx *bctx)
{
nsIInputStream *ret = NULL;
IUnknown *unk;
IBindStatusCallback *callback;
IServiceProvider *service_provider;
BINDINFO bindinfo;
DWORD bindf = 0;
DWORD post_len = 0, headers_len = 0;
LPWSTR headers = NULL;
WCHAR emptystr[] = {0};
char *data;
HRESULT hres;
static WCHAR _BSCB_Holder_[] =
{'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
/* FIXME: This should be done in URLMoniker */
if(!bctx)
return NULL;
hres = IBindCtx_GetObjectParam(bctx, _BSCB_Holder_, &unk);
if(FAILED(hres))
return NULL;
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback);
if(FAILED(hres)) {
IUnknown_Release(unk);
return NULL;
}
hres = IUnknown_QueryInterface(unk, &IID_IServiceProvider, (void**)&service_provider);
IUnknown_Release(unk);
if(SUCCEEDED(hres)) {
IHttpNegotiate *http_negotiate;
hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
(void**)&http_negotiate);
if(SUCCEEDED(hres)) {
hres = IHttpNegotiate_BeginningTransaction(http_negotiate, emptystr,
emptystr, 0, &headers);
IHttpNegotiate_Release(http_negotiate);
if(SUCCEEDED(hres) && headers)
headers_len = WideCharToMultiByte(CP_ACP, 0, headers, -1, NULL, 0, NULL, NULL);
}
IServiceProvider_Release(service_provider);
}
memset(&bindinfo, 0, sizeof(bindinfo));
bindinfo.cbSize = sizeof(bindinfo);
hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
if(SUCCEEDED(hres) && bindinfo.dwBindVerb == BINDVERB_POST)
post_len = bindinfo.cbstgmedData;
if(headers_len || post_len) {
int len = 0;
static const char content_length[] = "Content-Length: %u\r\n\r\n";
data = heap_alloc(headers_len+post_len+sizeof(content_length)+10);
if(headers_len) {
WideCharToMultiByte(CP_ACP, 0, headers, -1, data, headers_len, NULL, NULL);
len = fix_headers(data, post_len);
if(len >= 2 && (data[len-1] != '\n' || data[len-2] != '\r')) {
data[len++] = '\r';
data[len++] = '\n';
}
}
if(post_len) {
sprintf(data+len, content_length, post_len);
len += strlen(data+len);
memcpy(data+len, bindinfo.stgmedData.u.hGlobal, post_len);
}
TRACE("data = %s\n", debugstr_an(data, len+post_len));
if(len)
ret = create_nsstream(data, len+post_len);
}
CoTaskMemFree(headers);
ReleaseBindInfo(&bindinfo);
IBindStatusCallback_Release(callback);
return ret;
}
static BOOL use_gecko_script(LPCWSTR url)
{
static const WCHAR fileW[] = {'f','i','l','e',':'};
@@ -304,27 +181,15 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO
push_task(task);
if(This->nscontainer) {
nsIInputStream *post_data_stream = get_post_data_stream(pibc);
This->nscontainer->bscallback = bscallback;
nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url,
LOAD_FLAGS_NONE, NULL, post_data_stream, NULL);
LOAD_FLAGS_NONE, NULL, NULL, NULL);
This->nscontainer->bscallback = NULL;
if(post_data_stream)
nsIInputStream_Release(post_data_stream);
if(NS_SUCCEEDED(nsres)) {
/* FIXME: don't return here (URL Moniker needs to be good enough) */
if(NS_FAILED(nsres)) {
WARN("LoadURI failed: %08x\n", nsres);
IUnknown_Release((IUnknown*)bscallback);
CoTaskMemFree(url);
if(bind_complete)
*bind_complete = TRUE;
return S_OK;
}else if(nsres != WINE_NS_LOAD_FROM_MONIKER) {
WARN("LoadURI failed: %08x\n", nsres);
return E_FAIL;
}
}
@@ -337,7 +202,7 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO
return S_OK;
}
static HRESULT get_doc_string(HTMLDocument *This, char **str, DWORD *len)
static HRESULT get_doc_string(HTMLDocument *This, char **str)
{
nsIDOMNode *nsnode;
LPCWSTR strw;
@@ -362,9 +227,7 @@ static HRESULT get_doc_string(HTMLDocument *This, char **str, DWORD *len)
nsAString_GetData(&nsstr, &strw);
TRACE("%s\n", debugstr_w(strw));
*len = WideCharToMultiByte(CP_ACP, 0, strw, -1, NULL, 0, NULL, NULL);
*str = heap_alloc(*len);
WideCharToMultiByte(CP_ACP, 0, strw, -1, *str, *len, NULL, NULL);
*str = heap_strdupWtoA(strw);
nsAString_Finish(&nsstr);
@@ -583,7 +446,7 @@ static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileNam
{
HTMLDocument *This = PERSISTFILE_THIS(iface);
char *str;
DWORD len, written=0;
DWORD written=0;
HANDLE file;
HRESULT hres;
@@ -596,9 +459,9 @@ static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileNam
return E_FAIL;
}
hres = get_doc_string(This, &str, &len);
hres = get_doc_string(This, &str);
if(SUCCEEDED(hres))
WriteFile(file, str, len, &written, NULL);
WriteFile(file, str, strlen(str), &written, NULL);
CloseHandle(file);
return hres;
@@ -698,16 +561,16 @@ static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM
{
HTMLDocument *This = PERSTRINIT_THIS(iface);
char *str;
DWORD len, written=0;
DWORD written=0;
HRESULT hres;
TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty);
hres = get_doc_string(This, &str, &len);
hres = get_doc_string(This, &str);
if(FAILED(hres))
return hres;
hres = IStream_Write(pStm, str, len, &written);
hres = IStream_Write(pStm, str, strlen(str), &written);
if(FAILED(hres))
FIXME("Write failed: %08x\n", hres);
+31 -15
View File
@@ -67,12 +67,30 @@ typedef struct {
#define ACTSCPWIN(x) (&(x)->lpIActiveScriptSiteWindowVtbl)
#define ACTSCPDBG32(x) (&(x)->lpIActiveScriptSiteDebug32Vtbl)
static void set_script_prop(ScriptHost *script_host, DWORD property, VARIANT *val)
{
IActiveScriptProperty *script_prop;
HRESULT hres;
hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptProperty,
(void**)&script_prop);
if(FAILED(hres)) {
WARN("Could not get IActiveScriptProperty iface: %08x\n", hres);
return;
}
hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
IActiveScriptProperty_Release(script_prop);
if(FAILED(hres))
WARN("SetProperty(%x) failed: %08x\n", property, hres);
}
static BOOL init_script_engine(ScriptHost *script_host)
{
IActiveScriptProperty *property;
IObjectSafety *safety;
SCRIPTSTATE state;
DWORD supported_opts=0, enabled_opts=0;
VARIANT var;
HRESULT hres;
hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptParse, (void**)&script_host->parse);
@@ -104,20 +122,13 @@ static BOOL init_script_engine(ScriptHost *script_host)
if(FAILED(hres))
return FALSE;
hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptProperty, (void**)&property);
if(SUCCEEDED(hres)) {
VARIANT var;
V_VT(&var) = VT_I4;
V_I4(&var) = 1;
set_script_prop(script_host, SCRIPTPROP_INVOKEVERSIONING, &var);
V_VT(&var) = VT_BOOL;
V_BOOL(&var) = VARIANT_TRUE;
hres = IActiveScriptProperty_SetProperty(property, SCRIPTPROP_HACK_TRIDENTEVENTSINK, NULL, &var);
if(FAILED(hres))
WARN("SetProperty failed: %08x\n", hres);
IActiveScriptProperty_Release(property);
}else {
WARN("Could not get IActiveScriptProperty: %08x\n", hres);
}
V_VT(&var) = VT_BOOL;
V_BOOL(&var) = VARIANT_TRUE;
set_script_prop(script_host, SCRIPTPROP_HACK_TRIDENTEVENTSINK, &var);
hres = IActiveScriptParse64_InitNew(script_host->parse);
if(FAILED(hres)) {
@@ -146,8 +157,13 @@ static BOOL init_script_engine(ScriptHost *script_host)
hres = IActiveScript_AddNamedItem(script_host->script, windowW,
SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
if(FAILED(hres))
if(SUCCEEDED(hres)) {
V_VT(&var) = VT_BOOL;
V_BOOL(&var) = VARIANT_TRUE;
set_script_prop(script_host, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
}else {
WARN("AddNamedItem failed: %08x\n", hres);
}
hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptParseProcedure2,
(void**)&script_host->parse_proc);
+1 -1
View File
@@ -556,7 +556,7 @@ IUnknown* create_attribute( xmlNodePtr attribute )
This->lpVtbl = &domattr_vtbl;
This->ref = 1;
node = create_basic_node( attribute, (IUnknown*)&This->lpVtbl );
node = create_basic_node( attribute, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+1 -1
View File
@@ -779,7 +779,7 @@ IUnknown* create_cdata( xmlNodePtr text )
This->lpVtbl = &domcdata_vtbl;
This->ref = 1;
node = create_basic_node( text, (IUnknown*)&This->lpVtbl );
node = create_basic_node( text, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+1 -1
View File
@@ -777,7 +777,7 @@ IUnknown* create_comment( xmlNodePtr comment )
This->lpVtbl = &domcomment_vtbl;
This->ref = 1;
node = create_basic_node( comment, (IUnknown*)&This->lpVtbl );
node = create_basic_node( comment, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+1
View File
@@ -91,6 +91,7 @@ static REFIID tid_ids[] = {
&IID_IXMLDOMParseError,
&IID_IXMLDOMProcessingInstruction,
&IID_IXMLDOMSchemaCollection,
&IID_IXMLDOMSelection,
&IID_IXMLDOMText,
&IID_IXMLElement,
&IID_IXMLDOMDocument,
+1 -1
View File
@@ -529,7 +529,7 @@ IUnknown* create_doc_fragment( xmlNodePtr fragment )
This->lpVtbl = &domfrag_vtbl;
This->ref = 1;
node = create_basic_node( fragment, (IUnknown*)&This->lpVtbl );
node = create_basic_node( fragment, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+3 -8
View File
@@ -77,9 +77,6 @@ typedef struct _domdoc
/* IObjectSafety */
DWORD safeopt;
/* IDispatchEx */
DispatchEx dispex;
} domdoc;
/*
@@ -466,7 +463,7 @@ static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID rii
{
*ppvObject = &This->lpvtblISupportErrorInfo;
}
else if(dispex_query_interface(&This->dispex, riid, ppvObject))
else if(dispex_query_interface(&This->node->dispex, riid, ppvObject))
{
return *ppvObject ? S_OK : E_NOINTERFACE;
}
@@ -1043,7 +1040,7 @@ static HRESULT WINAPI domdoc_createElement(
xmldoc_add_orphan(xmlnode->doc, xmlnode);
TRACE("created xmlptr %p\n", xmlnode);
elem_unk = create_element(xmlnode, NULL);
elem_unk = create_element(xmlnode);
HeapFree(GetProcessHeap(), 0, xml_name);
hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
@@ -2218,15 +2215,13 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **docu
doc->safeopt = 0;
doc->bsc = NULL;
doc->node = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
doc->node = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex );
if(!doc->node)
{
HeapFree(GetProcessHeap(), 0, doc);
return E_FAIL;
}
init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
*document = (IXMLDOMDocument2*)&doc->lpVtbl;
TRACE("returning iface %p\n", *document);
+37 -78
View File
@@ -41,8 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
typedef struct _domelem
{
const struct IXMLDOMElementVtbl *lpVtbl;
const struct IUnknownVtbl *lpInternalUnkVtbl;
IUnknown *pUnkOuter;
LONG ref;
xmlnode *node;
} domelem;
@@ -52,11 +50,6 @@ static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpVtbl));
}
static inline domelem *impl_from_InternalUnknown( IUnknown *iface )
{
return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpInternalUnkVtbl));
}
static inline xmlNodePtr get_element( domelem *This )
{
return This->node->node;
@@ -68,23 +61,54 @@ static HRESULT WINAPI domelem_QueryInterface(
void** ppvObject )
{
domelem *This = impl_from_IXMLDOMElement( iface );
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject);
if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
IsEqualGUID( riid, &IID_IDispatch ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = &This->lpVtbl;
}
else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
{
*ppvObject = IXMLDOMNode_from_impl(This->node);
}
else
{
FIXME("interface %s not implemented\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
IUnknown_AddRef( (IUnknown*)*ppvObject );
return S_OK;
}
static ULONG WINAPI domelem_AddRef(
IXMLDOMElement *iface )
{
domelem *This = impl_from_IXMLDOMElement( iface );
return IUnknown_AddRef(This->pUnkOuter);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI domelem_Release(
IXMLDOMElement *iface )
{
domelem *This = impl_from_IXMLDOMElement( iface );
return IUnknown_Release(This->pUnkOuter);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
IXMLDOMNode_Release(IXMLDOMNode_from_impl(This->node));
heap_free(This);
}
return ref;
}
static HRESULT WINAPI domelem_GetTypeInfoCount(
@@ -727,66 +751,7 @@ static const struct IXMLDOMElementVtbl domelem_vtbl =
domelem_normalize,
};
static HRESULT WINAPI Internal_QueryInterface(
IUnknown *iface,
REFIID riid,
void** ppvObject )
{
domelem *This = impl_from_InternalUnknown( iface );
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
IsEqualGUID( riid, &IID_IDispatch ) ||
IsEqualGUID( riid, &IID_IUnknown ) )
{
*ppvObject = &This->lpVtbl;
}
else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
{
*ppvObject = IXMLDOMNode_from_impl(This->node);
}
else
{
FIXME("interface %s not implemented\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
IUnknown_AddRef( (IUnknown*)*ppvObject );
return S_OK;
}
static ULONG WINAPI Internal_AddRef(
IUnknown *iface )
{
domelem *This = impl_from_InternalUnknown( iface );
return InterlockedIncrement( &This->ref );
}
static ULONG WINAPI Internal_Release(
IUnknown *iface )
{
domelem *This = impl_from_InternalUnknown( iface );
ULONG ref;
ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
IXMLDOMNode_Release( IXMLDOMNode_from_impl(This->node) );
HeapFree( GetProcessHeap(), 0, This );
}
return ref;
}
static const struct IUnknownVtbl internal_unk_vtbl =
{
Internal_QueryInterface,
Internal_AddRef,
Internal_Release
};
IUnknown* create_element( xmlNodePtr element, IUnknown *pUnkOuter )
IUnknown* create_element( xmlNodePtr element )
{
domelem *This;
@@ -796,21 +761,15 @@ IUnknown* create_element( xmlNodePtr element, IUnknown *pUnkOuter )
This->lpVtbl = &domelem_vtbl;
This->ref = 1;
This->lpInternalUnkVtbl = &internal_unk_vtbl;
if(pUnkOuter)
This->pUnkOuter = pUnkOuter; /* Don't take a ref on outer Unknown */
else
This->pUnkOuter = (IUnknown *)&This->lpInternalUnkVtbl;
This->node = create_basic_node( element, (IUnknown*)&This->lpVtbl );
This->node = create_basic_node( element, (IUnknown*)&This->lpVtbl, NULL );
if(!This->node)
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
return (IUnknown*) &This->lpInternalUnkVtbl;
return (IUnknown*) &This->lpVtbl;
}
#endif
+1 -1
View File
@@ -528,7 +528,7 @@ IUnknown* create_doc_entity_ref( xmlNodePtr entity )
This->lpVtbl = &entityref_vtbl;
This->ref = 1;
node = create_basic_node( entity, (IUnknown*)&This->lpVtbl );
node = create_basic_node( entity, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+113 -111
View File
@@ -29,117 +29,6 @@
# error You must include config.h to use this header
#endif
#ifdef HAVE_LIBXML2
#ifdef HAVE_LIBXML_PARSER_H
#include <libxml/parser.h>
#endif
/* constructors */
extern IUnknown *create_domdoc( xmlNodePtr document );
extern IUnknown *create_xmldoc( void );
extern IXMLDOMNode *create_node( xmlNodePtr node );
extern IUnknown *create_element( xmlNodePtr element, IUnknown *pUnkOuter );
extern IUnknown *create_attribute( xmlNodePtr attribute );
extern IUnknown *create_text( xmlNodePtr text );
extern IUnknown *create_pi( xmlNodePtr pi );
extern IUnknown *create_comment( xmlNodePtr comment );
extern IUnknown *create_cdata( xmlNodePtr text );
extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr );
extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
extern IUnknown *create_doc_Implementation();
extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
extern HRESULT queryresult_create( xmlNodePtr, LPWSTR, IXMLDOMNodeList ** );
/* data accessors */
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
/* helpers */
extern xmlChar *xmlChar_from_wchar( LPWSTR str );
extern LONG xmldoc_add_ref( xmlDocPtr doc );
extern LONG xmldoc_release( xmlDocPtr doc );
extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
extern xmlDocPtr parse_xml(char *ptr, int len);
/* IXMLDOMNode Internal Structure */
typedef struct _xmlnode
{
const struct IXMLDOMNodeVtbl *lpVtbl;
const struct IUnknownVtbl *lpInternalUnkVtbl;
IUnknown *pUnkOuter;
LONG ref;
xmlNodePtr node;
} xmlnode;
static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
{
return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
}
static inline IXMLDOMNode *IXMLDOMNode_from_impl(xmlnode *This)
{
return (IXMLDOMNode*)&This->lpVtbl;
}
extern xmlnode *create_basic_node(xmlNodePtr,IUnknown*);
extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document);
static inline BSTR bstr_from_xmlChar(const xmlChar *str)
{
BSTR ret = NULL;
if(str) {
DWORD len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, NULL, 0);
ret = SysAllocStringLen(NULL, len-1);
if(ret)
MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)str, -1, ret, len);
}
return ret;
}
#endif
void* libxslt_handle;
#ifdef SONAME_LIBXSLT
# ifdef HAVE_LIBXSLT_PATTERN_H
# include <libxslt/pattern.h>
# endif
# ifdef HAVE_LIBXSLT_TRANSFORM_H
# include <libxslt/transform.h>
# endif
# include <libxslt/xsltutils.h>
# include <libxslt/xsltInternals.h>
# define MAKE_FUNCPTR(f) extern typeof(f) * p##f
MAKE_FUNCPTR(xsltApplyStylesheet);
MAKE_FUNCPTR(xsltCleanupGlobals);
MAKE_FUNCPTR(xsltFreeStylesheet);
MAKE_FUNCPTR(xsltParseStylesheetDoc);
# undef MAKE_FUNCPTR
#endif
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
LONG line, LONG linepos, LONG filepos );
extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj);
typedef struct bsc_t bsc_t;
HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**);
void detach_bsc(bsc_t*);
/* typelibs */
typedef enum tid_t {
IXMLDOMAttribute_tid,
@@ -157,6 +46,7 @@ typedef enum tid_t {
IXMLDOMParseError_tid,
IXMLDOMProcessingInstruction_tid,
IXMLDOMSchemaCollection_tid,
IXMLDOMSelection_tid,
IXMLDOMText_tid,
IXMLElement_tid,
IXMLDocument_tid,
@@ -210,6 +100,118 @@ typedef struct {
void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*);
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
#ifdef HAVE_LIBXML2
#ifdef HAVE_LIBXML_PARSER_H
#include <libxml/parser.h>
#endif
/* constructors */
extern IUnknown *create_domdoc( xmlNodePtr document );
extern IUnknown *create_xmldoc( void );
extern IXMLDOMNode *create_node( xmlNodePtr node );
extern IUnknown *create_element( xmlNodePtr element );
extern IUnknown *create_attribute( xmlNodePtr attribute );
extern IUnknown *create_text( xmlNodePtr text );
extern IUnknown *create_pi( xmlNodePtr pi );
extern IUnknown *create_comment( xmlNodePtr comment );
extern IUnknown *create_cdata( xmlNodePtr text );
extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr );
extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
extern IUnknown *create_doc_Implementation();
extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
extern HRESULT queryresult_create( xmlNodePtr, LPWSTR, IXMLDOMNodeList ** );
/* data accessors */
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
/* helpers */
extern xmlChar *xmlChar_from_wchar( LPWSTR str );
extern LONG xmldoc_add_ref( xmlDocPtr doc );
extern LONG xmldoc_release( xmlDocPtr doc );
extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
extern xmlDocPtr parse_xml(char *ptr, int len);
/* IXMLDOMNode Internal Structure */
typedef struct _xmlnode
{
DispatchEx dispex;
const struct IXMLDOMNodeVtbl *lpVtbl;
const struct IUnknownVtbl *lpInternalUnkVtbl;
IUnknown *pUnkOuter;
LONG ref;
xmlNodePtr node;
} xmlnode;
static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
{
return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
}
static inline IXMLDOMNode *IXMLDOMNode_from_impl(xmlnode *This)
{
return (IXMLDOMNode*)&This->lpVtbl;
}
extern xmlnode *create_basic_node(xmlNodePtr,IUnknown*,dispex_static_data_t*);
extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document);
static inline BSTR bstr_from_xmlChar(const xmlChar *str)
{
BSTR ret = NULL;
if(str) {
DWORD len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, NULL, 0);
ret = SysAllocStringLen(NULL, len-1);
if(ret)
MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)str, -1, ret, len);
}
return ret;
}
#endif
void* libxslt_handle;
#ifdef SONAME_LIBXSLT
# ifdef HAVE_LIBXSLT_PATTERN_H
# include <libxslt/pattern.h>
# endif
# ifdef HAVE_LIBXSLT_TRANSFORM_H
# include <libxslt/transform.h>
# endif
# include <libxslt/xsltutils.h>
# include <libxslt/xsltInternals.h>
# define MAKE_FUNCPTR(f) extern typeof(f) * p##f
MAKE_FUNCPTR(xsltApplyStylesheet);
MAKE_FUNCPTR(xsltCleanupGlobals);
MAKE_FUNCPTR(xsltFreeStylesheet);
MAKE_FUNCPTR(xsltParseStylesheetDoc);
# undef MAKE_FUNCPTR
#endif
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
LONG line, LONG linepos, LONG filepos );
extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj );
extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj);
typedef struct bsc_t bsc_t;
HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**);
void detach_bsc(bsc_t*);
/* memory allocation functions */
static inline void *heap_alloc(size_t len)
+6 -3
View File
@@ -1542,7 +1542,7 @@ static const struct IUnknownVtbl internal_unk_vtbl =
Internal_Release
};
xmlnode *create_basic_node( xmlNodePtr node, IUnknown *pUnkOuter )
xmlnode *create_basic_node( xmlNodePtr node, IUnknown *pUnkOuter, dispex_static_data_t *dispex_data )
{
xmlnode *This;
@@ -1561,6 +1561,9 @@ xmlnode *create_basic_node( xmlNodePtr node, IUnknown *pUnkOuter )
else
This->pUnkOuter = (IUnknown *)&This->lpInternalUnkVtbl;
if(dispex_data)
init_dispex(&This->dispex, This->pUnkOuter, dispex_data);
This->ref = 1;
This->node = node;
@@ -1580,7 +1583,7 @@ IXMLDOMNode *create_node( xmlNodePtr node )
switch(node->type)
{
case XML_ELEMENT_NODE:
pUnk = create_element( node, NULL );
pUnk = create_element( node );
break;
case XML_ATTRIBUTE_NODE:
pUnk = create_attribute( node );
@@ -1599,7 +1602,7 @@ IXMLDOMNode *create_node( xmlNodePtr node )
break;
default:
FIXME("only creating basic node for type %d\n", node->type);
pUnk = (IUnknown*)&create_basic_node( node, NULL )->lpInternalUnkVtbl;
pUnk = (IUnknown*)&create_basic_node( node, NULL, NULL )->lpInternalUnkVtbl;
}
hr = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMNode, (LPVOID*)&ret);
+1 -1
View File
@@ -614,7 +614,7 @@ IUnknown* create_pi( xmlNodePtr pi )
This->lpVtbl = &dom_pi_vtbl;
This->ref = 1;
node = create_basic_node( pi, (IUnknown*)&This->lpVtbl );
node = create_basic_node( pi, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);
+1 -1
View File
@@ -366,7 +366,7 @@ static const tid_t queryresult_iface_tids[] = {
};
static dispex_static_data_t queryresult_dispex = {
&queryresult_dispex_vtbl,
IXMLDOMNodeList_tid,
IXMLDOMSelection_tid,
NULL,
queryresult_iface_tids
};
+1 -1
View File
@@ -781,7 +781,7 @@ IUnknown* create_text( xmlNodePtr text )
This->lpVtbl = &domtext_vtbl;
This->ref = 1;
node = create_basic_node( text, (IUnknown*)&This->lpVtbl );
node = create_basic_node( text, (IUnknown*)&This->lpVtbl, NULL );
if(!node)
{
HeapFree(GetProcessHeap(), 0, This);