mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
- Sync msctf, mshtml and msxml3 with Wine 1.1.29
svn path=/trunk/; revision=42994
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -91,6 +91,7 @@ static REFIID tid_ids[] = {
|
||||
&IID_IXMLDOMParseError,
|
||||
&IID_IXMLDOMProcessingInstruction,
|
||||
&IID_IXMLDOMSchemaCollection,
|
||||
&IID_IXMLDOMSelection,
|
||||
&IID_IXMLDOMText,
|
||||
&IID_IXMLElement,
|
||||
&IID_IXMLDOMDocument,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user