mirror of
https://github.com/reactos/reactos.git
synced 2024-12-04 17:03:30 +08:00
- Sync msctf, mlang, inetmib1, inetcomm with Wine 1.1.22
svn path=/trunk/; revision=41065
This commit is contained in:
parent
05625d8565
commit
2607d66f40
@ -732,7 +732,7 @@ static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR ps
|
||||
SMTPTransport *This = (SMTPTransport *)iface;
|
||||
const char szCommandFormat[] = "MAIL FROM: <%s>\n";
|
||||
char *szCommand;
|
||||
int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom);
|
||||
int len;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(pszEmailFrom));
|
||||
@ -740,6 +740,7 @@ static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR ps
|
||||
if (!pszEmailFrom)
|
||||
return E_INVALIDARG;
|
||||
|
||||
len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom);
|
||||
szCommand = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (!szCommand)
|
||||
return E_OUTOFMEMORY;
|
||||
@ -758,7 +759,7 @@ static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR ps
|
||||
SMTPTransport *This = (SMTPTransport *)iface;
|
||||
const char szCommandFormat[] = "RCPT TO: <%s>\n";
|
||||
char *szCommand;
|
||||
int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo);
|
||||
int len;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(pszEmailTo));
|
||||
@ -766,6 +767,7 @@ static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR ps
|
||||
if (!pszEmailTo)
|
||||
return E_INVALIDARG;
|
||||
|
||||
len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo);
|
||||
szCommand = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (!szCommand)
|
||||
return E_OUTOFMEMORY;
|
||||
@ -833,7 +835,7 @@ static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface,
|
||||
SMTPTransport *This = (SMTPTransport *)iface;
|
||||
const char szCommandFormat[] = "AUTH %s\n";
|
||||
char *szCommand;
|
||||
int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType);
|
||||
int len;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(pszAuthType));
|
||||
@ -841,6 +843,7 @@ static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface,
|
||||
if (!pszAuthType)
|
||||
return E_INVALIDARG;
|
||||
|
||||
len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType);
|
||||
szCommand = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (!szCommand)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -143,7 +143,10 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
||||
|
||||
copyInt(&pVarBind->value, &numIfs);
|
||||
if (bPduType == SNMP_PDU_GETNEXT)
|
||||
{
|
||||
SnmpUtilOidFree(&pVarBind->name);
|
||||
SnmpUtilOidCpy(&pVarBind->name, &numberOid);
|
||||
}
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOERROR;
|
||||
}
|
||||
else
|
||||
@ -320,7 +323,27 @@ static DWORD oidToIpAddr(AsnObjectIdentifier *oid)
|
||||
typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst);
|
||||
typedef int (*compareFunc)(const void *key, const void *value);
|
||||
|
||||
static UINT findValueInTable(AsnObjectIdentifier *oid,
|
||||
/* Finds the first value in the table that matches key. Returns its 1-based
|
||||
* index if found, or 0 if not found.
|
||||
*/
|
||||
static UINT findValueInTable(const void *key,
|
||||
struct GenericTable *table, size_t tableEntrySize, compareFunc compare)
|
||||
{
|
||||
UINT index = 0;
|
||||
void *value;
|
||||
|
||||
value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
|
||||
compare);
|
||||
if (value)
|
||||
index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + 1;
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Finds the first value in the table that matches oid, using makeKey to
|
||||
* convert the oid to a key for comparison. Returns the value's 1-based
|
||||
* index if found, or 0 if not found.
|
||||
*/
|
||||
static UINT findOidInTable(AsnObjectIdentifier *oid,
|
||||
struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
|
||||
compareFunc compare)
|
||||
{
|
||||
@ -329,14 +352,50 @@ static UINT findValueInTable(AsnObjectIdentifier *oid,
|
||||
|
||||
if (key)
|
||||
{
|
||||
void *value;
|
||||
|
||||
makeKey(oid, key);
|
||||
value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
|
||||
compare);
|
||||
if (value)
|
||||
index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize
|
||||
+ 1;
|
||||
index = findValueInTable(key, table, tableEntrySize, compare);
|
||||
HeapFree(GetProcessHeap(), 0, key);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Finds the first successor to the value in the table that does matches oid,
|
||||
* using makeKey to convert the oid to a key for comparison. A successor is
|
||||
* a value that does not match oid, so if multiple entries match an oid, only
|
||||
* the first will ever be returned using this method.
|
||||
* Returns the successor's 1-based index if found, or 0 if not found.
|
||||
*/
|
||||
static UINT findNextOidInTable(AsnObjectIdentifier *oid,
|
||||
struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
|
||||
compareFunc compare)
|
||||
{
|
||||
UINT index = 0;
|
||||
void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);
|
||||
|
||||
if (key)
|
||||
{
|
||||
makeKey(oid, key);
|
||||
index = findValueInTable(key, table, tableEntrySize, compare);
|
||||
if (index == 0)
|
||||
{
|
||||
/* Not found in table. If it's less than the first entry, return
|
||||
* the first index. Otherwise just return 0 and let the caller
|
||||
* handle finding the successor.
|
||||
*/
|
||||
if (compare(key, table->entries) < 0)
|
||||
index = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip any entries that match the same key. This enumeration will
|
||||
* be incomplete, but it's what Windows appears to do if there are
|
||||
* multiple entries with the same index in a table, and it avoids
|
||||
* an infinite loop.
|
||||
*/
|
||||
for (++index; index <= table->numEntries && compare(key,
|
||||
&table->entries[tableEntrySize * index]) == 0; ++index)
|
||||
;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, key);
|
||||
}
|
||||
return index;
|
||||
@ -397,12 +456,12 @@ static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid,
|
||||
}
|
||||
else
|
||||
{
|
||||
AsnObjectIdentifier ipOid = { instanceLen,
|
||||
AsnObjectIdentifier instanceOid = { instanceLen,
|
||||
oid->ids + base->idLength + 1 };
|
||||
|
||||
*instance = findValueInTable(&ipOid, table, tableEntrySize,
|
||||
makeKey, compare) + 1;
|
||||
if (*instance > table->numEntries)
|
||||
*instance = findNextOidInTable(&instanceOid, table,
|
||||
tableEntrySize, makeKey, compare);
|
||||
if (!*instance || *instance > table->numEntries)
|
||||
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
}
|
||||
@ -418,10 +477,10 @@ static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid,
|
||||
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
else
|
||||
{
|
||||
AsnObjectIdentifier ipOid = { instanceLen,
|
||||
AsnObjectIdentifier instanceOid = { instanceLen,
|
||||
oid->ids + base->idLength + 1 };
|
||||
|
||||
*instance = findValueInTable(&ipOid, table, tableEntrySize,
|
||||
*instance = findOidInTable(&instanceOid, table, tableEntrySize,
|
||||
makeKey, compare);
|
||||
if (!*instance)
|
||||
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
@ -440,6 +499,7 @@ static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
|
||||
AsnObjectIdentifier oid;
|
||||
INT ret;
|
||||
|
||||
SnmpUtilOidFree(dst);
|
||||
ret = SnmpUtilOidCpy(dst, base);
|
||||
if (ret)
|
||||
{
|
||||
@ -1311,7 +1371,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
||||
* so we have to continue until an implementation handles the
|
||||
* query or we exhaust the table of supported OIDs.
|
||||
*/
|
||||
for (; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
|
||||
for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
|
||||
matchingIndex < DEFINE_SIZEOF(supportedIDs);
|
||||
matchingIndex++)
|
||||
{
|
||||
|
@ -1939,7 +1939,7 @@ static HRESULT WINAPI fnIMLangFontLink_GetStrCodePages(
|
||||
}
|
||||
|
||||
if (pdwCodePages) *pdwCodePages = cps;
|
||||
if (pcchCodePages) *pcchCodePages = i;
|
||||
if (pcchCodePages) *pcchCodePages = min( i + 1, cchSrc );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -58,14 +58,24 @@ typedef struct tagContextSink {
|
||||
typedef struct tagContext {
|
||||
const ITfContextVtbl *ContextVtbl;
|
||||
const ITfSourceVtbl *SourceVtbl;
|
||||
/* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
|
||||
/* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
|
||||
/* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
|
||||
/* const ITfInsertAtSelectionVtbl *InsertAtSelectionVtbl; */
|
||||
/* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
|
||||
/* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
|
||||
/* const ITfSourceSingleVtbl *SourceSingleVtbl; */
|
||||
LONG refCount;
|
||||
BOOL connected;
|
||||
|
||||
TfClientId tidOwner;
|
||||
TfEditCookie defaultCookie;
|
||||
|
||||
ITextStoreACP *pITextStoreACP;
|
||||
ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
|
||||
|
||||
ITextStoreACPSink *pITextStoreACPSink;
|
||||
ITfEditSession* currentEditSession;
|
||||
|
||||
/* kept as separate lists to reduce unnecessary iterations */
|
||||
struct list pContextKeyEventSink;
|
||||
@ -76,9 +86,14 @@ typedef struct tagContext {
|
||||
|
||||
} Context;
|
||||
|
||||
typedef struct tagEditCookie {
|
||||
DWORD lockType;
|
||||
Context *pOwningContext;
|
||||
} EditCookie;
|
||||
|
||||
typedef struct tagTextStoreACPSink {
|
||||
const ITextStoreACPSinkVtbl *TextStoreACPSinkVtbl;
|
||||
/* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
|
||||
LONG refCount;
|
||||
|
||||
Context *pContext;
|
||||
@ -101,6 +116,7 @@ static void free_sink(ContextSink *sink)
|
||||
static void Context_Destructor(Context *This)
|
||||
{
|
||||
struct list *cursor, *cursor2;
|
||||
EditCookie *cookie;
|
||||
TRACE("destroying %p\n", This);
|
||||
|
||||
if (This->pITextStoreACPSink)
|
||||
@ -115,6 +131,13 @@ static void Context_Destructor(Context *This)
|
||||
if (This->pITfContextOwnerCompositionSink)
|
||||
ITextStoreACPSink_Release(This->pITfContextOwnerCompositionSink);
|
||||
|
||||
if (This->defaultCookie)
|
||||
{
|
||||
cookie = remove_Cookie(This->defaultCookie);
|
||||
HeapFree(GetProcessHeap(),0,cookie);
|
||||
This->defaultCookie = 0;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pContextKeyEventSink)
|
||||
{
|
||||
ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
|
||||
@ -197,9 +220,53 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
|
||||
TfClientId tid, ITfEditSession *pes, DWORD dwFlags,
|
||||
HRESULT *phrSession)
|
||||
{
|
||||
HRESULT hr;
|
||||
Context *This = (Context *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
DWORD dwLockFlags = 0x0;
|
||||
TS_STATUS status;
|
||||
|
||||
TRACE("(%p) %i %p %x %p\n",This, tid, pes, dwFlags, phrSession);
|
||||
|
||||
if (!(dwFlags & TF_ES_READ) && !(dwFlags & TF_ES_READWRITE))
|
||||
{
|
||||
*phrSession = E_FAIL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!This->pITextStoreACP)
|
||||
{
|
||||
FIXME("No ITextStoreACP avaliable\n");
|
||||
*phrSession = E_FAIL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (!(dwFlags & TF_ES_ASYNC))
|
||||
dwLockFlags |= TS_LF_SYNC;
|
||||
|
||||
if ((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE)
|
||||
dwLockFlags |= TS_LF_READWRITE;
|
||||
else if (dwFlags & TF_ES_READ)
|
||||
dwLockFlags |= TS_LF_READ;
|
||||
|
||||
/* TODO: cache this */
|
||||
ITextStoreACP_GetStatus(This->pITextStoreACP, &status);
|
||||
|
||||
if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (status.dwDynamicFlags & TS_SD_READONLY))
|
||||
{
|
||||
*phrSession = TS_E_READONLY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (FAILED (ITfEditSession_QueryInterface(pes, &IID_ITfEditSession, (LPVOID*)&This->currentEditSession)))
|
||||
{
|
||||
*phrSession = E_FAIL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
hr = ITextStoreACP_RequestLock(This->pITextStoreACP, dwLockFlags, phrSession);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Context_InWriteSession (ITfContext *iface,
|
||||
@ -216,8 +283,59 @@ static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
|
||||
TF_SELECTION *pSelection, ULONG *pcFetched)
|
||||
{
|
||||
Context *This = (Context *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
EditCookie *cookie;
|
||||
ULONG count, i;
|
||||
ULONG totalFetched = 0;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!pSelection || !pcFetched)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pcFetched = 0;
|
||||
|
||||
if (!This->connected)
|
||||
return TF_E_DISCONNECTED;
|
||||
|
||||
if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
|
||||
return TF_E_NOLOCK;
|
||||
|
||||
if (!This->pITextStoreACP)
|
||||
{
|
||||
FIXME("Context does not have a ITextStoreACP\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
cookie = get_Cookie_data(ec);
|
||||
|
||||
if (ulIndex == TF_DEFAULT_SELECTION)
|
||||
count = 1;
|
||||
else
|
||||
count = ulCount;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
DWORD fetched;
|
||||
TS_SELECTION_ACP acps;
|
||||
|
||||
hr = ITextStoreACP_GetSelection(This->pITextStoreACP, ulIndex + i,
|
||||
1, &acps, &fetched);
|
||||
|
||||
if (hr == TS_E_NOLOCK)
|
||||
return TF_E_NOLOCK;
|
||||
else if (SUCCEEDED(hr))
|
||||
{
|
||||
pSelection[totalFetched].style.ase = acps.style.ase;
|
||||
pSelection[totalFetched].style.fInterimChar = acps.style.fInterimChar;
|
||||
Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, acps.acpStart, acps.acpEnd, &pSelection[totalFetched].range);
|
||||
totalFetched ++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
*pcFetched = totalFetched;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
|
||||
@ -232,16 +350,53 @@ static HRESULT WINAPI Context_GetStart (ITfContext *iface,
|
||||
TfEditCookie ec, ITfRange **ppStart)
|
||||
{
|
||||
Context *This = (Context *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
EditCookie *cookie;
|
||||
TRACE("(%p) %i %p\n",This,ec,ppStart);
|
||||
|
||||
if (!ppStart)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppStart = NULL;
|
||||
|
||||
if (!This->connected)
|
||||
return TF_E_DISCONNECTED;
|
||||
|
||||
if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
|
||||
return TF_E_NOLOCK;
|
||||
|
||||
cookie = get_Cookie_data(ec);
|
||||
return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, 0, 0, ppStart);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
|
||||
TfEditCookie ec, ITfRange **ppEnd)
|
||||
{
|
||||
Context *This = (Context *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
EditCookie *cookie;
|
||||
LONG end;
|
||||
TRACE("(%p) %i %p\n",This,ec,ppEnd);
|
||||
|
||||
if (!ppEnd)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppEnd = NULL;
|
||||
|
||||
if (!This->connected)
|
||||
return TF_E_DISCONNECTED;
|
||||
|
||||
if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
|
||||
return TF_E_NOLOCK;
|
||||
|
||||
if (!This->pITextStoreACP)
|
||||
{
|
||||
FIXME("Context does not have a ITextStoreACP\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
cookie = get_Cookie_data(ec);
|
||||
ITextStoreACP_GetEndACP(This->pITextStoreACP,&end);
|
||||
|
||||
return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, end, end, ppEnd);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
|
||||
@ -376,7 +531,7 @@ static WINAPI HRESULT ContextSource_AdviseSink(ITfSource *iface,
|
||||
es = HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink));
|
||||
if (!es)
|
||||
return E_OUTOFMEMORY;
|
||||
if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&es->interfaces.pITfTextEditSink)))
|
||||
if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&es->interfaces.pITfTextEditSink)))
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,es);
|
||||
return CONNECT_E_CANNOTCONNECT;
|
||||
@ -427,27 +582,34 @@ static const ITfSourceVtbl Context_SourceVtbl =
|
||||
HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore)
|
||||
{
|
||||
Context *This;
|
||||
EditCookie *cookie;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
|
||||
if (This == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
|
||||
if (cookie == NULL)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
|
||||
|
||||
This->ContextVtbl= &Context_ContextVtbl;
|
||||
This->SourceVtbl = &Context_SourceVtbl;
|
||||
This->refCount = 1;
|
||||
This->tidOwner = tidOwner;
|
||||
This->connected = FALSE;
|
||||
|
||||
cookie->lockType = TF_ES_READ;
|
||||
cookie->pOwningContext = This;
|
||||
|
||||
if (punk)
|
||||
{
|
||||
if (SUCCEEDED(IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
|
||||
(LPVOID*)&This->pITextStoreACP)))
|
||||
{
|
||||
if (SUCCEEDED(TextStoreACPSink_Constructor(&This->pITextStoreACPSink, This)))
|
||||
ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
|
||||
(IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
|
||||
}
|
||||
IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
|
||||
(LPVOID*)&This->pITextStoreACP);
|
||||
|
||||
IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
|
||||
(LPVOID*)&This->pITfContextOwnerCompositionSink);
|
||||
@ -456,10 +618,8 @@ HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **pp
|
||||
FIXME("Unhandled pUnk\n");
|
||||
}
|
||||
|
||||
TRACE("returning %p\n", This);
|
||||
*ppOut = (ITfContext*)This;
|
||||
/* FIXME */
|
||||
*pecTextStore = 0xdeaddead;
|
||||
This->defaultCookie = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE,cookie);
|
||||
*pecTextStore = This->defaultCookie;
|
||||
|
||||
list_init(&This->pContextKeyEventSink);
|
||||
list_init(&This->pEditTransactionSink);
|
||||
@ -467,6 +627,37 @@ HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **pp
|
||||
list_init(&This->pTextEditSink);
|
||||
list_init(&This->pTextLayoutSink);
|
||||
|
||||
*ppOut = (ITfContext*)This;
|
||||
TRACE("returning %p\n", This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Context_Initialize(ITfContext *iface)
|
||||
{
|
||||
Context *This = (Context *)iface;
|
||||
|
||||
if (This->pITextStoreACP)
|
||||
{
|
||||
if (SUCCEEDED(TextStoreACPSink_Constructor(&This->pITextStoreACPSink, This)))
|
||||
ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
|
||||
(IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
|
||||
}
|
||||
This->connected = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Context_Uninitialize(ITfContext *iface)
|
||||
{
|
||||
Context *This = (Context *)iface;
|
||||
|
||||
if (This->pITextStoreACPSink)
|
||||
{
|
||||
ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)This->pITextStoreACPSink);
|
||||
if (ITextStoreACPSink_Release(This->pITextStoreACPSink) == 0)
|
||||
This->pITextStoreACPSink = NULL;
|
||||
}
|
||||
This->connected = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -564,8 +755,36 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
|
||||
DWORD dwLockFlags)
|
||||
{
|
||||
TextStoreACPSink *This = (TextStoreACPSink *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
HRESULT hr;
|
||||
EditCookie *cookie;
|
||||
TfEditCookie ec;
|
||||
|
||||
TRACE("(%p) %x\n",This, dwLockFlags);
|
||||
|
||||
if (!This->pContext || !This->pContext->currentEditSession)
|
||||
{
|
||||
ERR("OnLockGranted called on a context without a current edit session\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
|
||||
if (!cookie)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
cookie->lockType = dwLockFlags;
|
||||
cookie->pOwningContext = This->pContext;
|
||||
ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
|
||||
|
||||
hr = ITfEditSession_DoEditSession(This->pContext->currentEditSession, ec);
|
||||
|
||||
ITfEditSession_Release(This->pContext->currentEditSession);
|
||||
This->pContext->currentEditSession = NULL;
|
||||
|
||||
/* Edit Cookie is only valid during the edit session */
|
||||
cookie = remove_Cookie(ec);
|
||||
HeapFree(GetProcessHeap(),0,cookie);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)
|
||||
|
@ -138,6 +138,7 @@ static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
|
||||
This->contextStack[0] = check;
|
||||
|
||||
ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
|
||||
Context_Initialize(check);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -153,11 +154,13 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
|
||||
{
|
||||
ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
|
||||
ITfContext_Release(This->contextStack[0]);
|
||||
Context_Uninitialize(This->contextStack[0]);
|
||||
}
|
||||
if (This->contextStack[1])
|
||||
{
|
||||
ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
|
||||
ITfContext_Release(This->contextStack[1]);
|
||||
Context_Uninitialize(This->contextStack[1]);
|
||||
}
|
||||
This->contextStack[0] = This->contextStack[1] = NULL;
|
||||
ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
|
||||
@ -172,6 +175,7 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
|
||||
|
||||
ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
|
||||
ITfContext_Release(This->contextStack[0]);
|
||||
Context_Uninitialize(This->contextStack[0]);
|
||||
This->contextStack[0] = This->contextStack[1];
|
||||
This->contextStack[1] = NULL;
|
||||
|
||||
|
@ -32,8 +32,10 @@
|
||||
#include "shlwapi.h"
|
||||
#include "winerror.h"
|
||||
#include "objbase.h"
|
||||
#include "olectl.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#include "msctf.h"
|
||||
#include "msctf_internal.h"
|
||||
@ -45,11 +47,26 @@ static const WCHAR szwEnabled[] = {'E','n','a','b','l','e','d',0};
|
||||
static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
|
||||
static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
|
||||
|
||||
typedef struct tagInputProcessorProfilesSink {
|
||||
struct list entry;
|
||||
union {
|
||||
/* InputProcessorProfile Sinks */
|
||||
IUnknown *pIUnknown;
|
||||
ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
|
||||
} interfaces;
|
||||
} InputProcessorProfilesSink;
|
||||
|
||||
typedef struct tagInputProcessorProfiles {
|
||||
const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
|
||||
const ITfSourceVtbl *SourceVtbl;
|
||||
/* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */
|
||||
/* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
|
||||
/* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
|
||||
LONG refCount;
|
||||
|
||||
LANGID currentLanguage;
|
||||
|
||||
struct list LanguageProfileNotifySink;
|
||||
} InputProcessorProfiles;
|
||||
|
||||
typedef struct tagProfilesEnumGuid {
|
||||
@ -78,9 +95,30 @@ typedef struct tagEnumTfLanguageProfiles {
|
||||
static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
|
||||
static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
|
||||
|
||||
static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface)
|
||||
{
|
||||
return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl));
|
||||
}
|
||||
|
||||
static void free_sink(InputProcessorProfilesSink *sink)
|
||||
{
|
||||
IUnknown_Release(sink->interfaces.pIUnknown);
|
||||
HeapFree(GetProcessHeap(),0,sink);
|
||||
}
|
||||
|
||||
static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
|
||||
{
|
||||
struct list *cursor, *cursor2;
|
||||
TRACE("destroying %p\n", This);
|
||||
|
||||
/* free sinks */
|
||||
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink)
|
||||
{
|
||||
InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
|
||||
list_remove(cursor);
|
||||
free_sink(sink);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
@ -122,6 +160,10 @@ static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorPro
|
||||
{
|
||||
*ppvOut = This;
|
||||
}
|
||||
else if (IsEqualIID(iid, &IID_ITfSource))
|
||||
{
|
||||
*ppvOut = &This->SourceVtbl;
|
||||
}
|
||||
|
||||
if (*ppvOut)
|
||||
{
|
||||
@ -536,6 +578,92 @@ static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessor
|
||||
InputProcessorProfiles_SubstituteKeyboardLayout
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* ITfSource functions
|
||||
*****************************************************/
|
||||
static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
|
||||
return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IPPSource_AddRef(ITfSource *iface)
|
||||
{
|
||||
InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
|
||||
return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IPPSource_Release(ITfSource *iface)
|
||||
{
|
||||
InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
|
||||
return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This);
|
||||
}
|
||||
|
||||
static WINAPI HRESULT IPPSource_AdviseSink(ITfSource *iface,
|
||||
REFIID riid, IUnknown *punk, DWORD *pdwCookie)
|
||||
{
|
||||
InputProcessorProfilesSink *ipps;
|
||||
InputProcessorProfiles *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_ITfLanguageProfileNotifySink))
|
||||
{
|
||||
ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink));
|
||||
if (!ipps)
|
||||
return E_OUTOFMEMORY;
|
||||
if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink)))
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,ipps);
|
||||
return CONNECT_E_CANNOTCONNECT;
|
||||
}
|
||||
list_add_head(&This->LanguageProfileNotifySink,&ipps->entry);
|
||||
*pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps);
|
||||
}
|
||||
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 IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
|
||||
{
|
||||
InputProcessorProfilesSink *sink;
|
||||
InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
|
||||
|
||||
TRACE("(%p) %x\n",This,pdwCookie);
|
||||
|
||||
if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK)
|
||||
return E_INVALIDARG;
|
||||
|
||||
sink = (InputProcessorProfilesSink*)remove_Cookie(pdwCookie);
|
||||
if (!sink)
|
||||
return CONNECT_E_NOCONNECTION;
|
||||
|
||||
list_remove(&sink->entry);
|
||||
free_sink(sink);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl =
|
||||
{
|
||||
IPPSource_QueryInterface,
|
||||
IPPSource_AddRef,
|
||||
IPPSource_Release,
|
||||
|
||||
IPPSource_AdviseSink,
|
||||
IPPSource_UnadviseSink,
|
||||
};
|
||||
|
||||
HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
|
||||
{
|
||||
InputProcessorProfiles *This;
|
||||
@ -547,9 +675,12 @@ HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
|
||||
This->SourceVtbl = &InputProcessorProfiles_SourceVtbl;
|
||||
This->refCount = 1;
|
||||
This->currentLanguage = GetUserDefaultLCID();
|
||||
|
||||
list_init(&This->LanguageProfileNotifySink);
|
||||
|
||||
TRACE("returning %p\n", This);
|
||||
*ppOut = (IUnknown *)This;
|
||||
return S_OK;
|
||||
|
@ -55,6 +55,7 @@ typedef struct {
|
||||
TF_LANGUAGEPROFILE LanguageProfile;
|
||||
ITfTextInputProcessor *pITfTextInputProcessor;
|
||||
ITfThreadMgr *pITfThreadMgr;
|
||||
ITfKeyEventSink *pITfKeyEventSink;
|
||||
TfClientId tid;
|
||||
} ActivatedTextService;
|
||||
|
||||
@ -357,14 +358,6 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
|
||||
actsvr = HeapAlloc(GetProcessHeap(),0,sizeof(ActivatedTextService));
|
||||
if (!actsvr) return E_OUTOFMEMORY;
|
||||
|
||||
entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,actsvr);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ITfThreadMgr_QueryInterface(tm,&IID_ITfClientId,(LPVOID)&clientid);
|
||||
ITfClientId_GetClientId(clientid, &lp->clsid, &actsvr->tid);
|
||||
ITfClientId_Release(clientid);
|
||||
@ -378,6 +371,7 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
|
||||
actsvr->pITfTextInputProcessor = NULL;
|
||||
actsvr->LanguageProfile = *lp;
|
||||
actsvr->LanguageProfile.fActive = TRUE;
|
||||
actsvr->pITfKeyEventSink = NULL;
|
||||
|
||||
/* get TIP category */
|
||||
if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr)))
|
||||
@ -402,6 +396,14 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
|
||||
if (activated > 0)
|
||||
activate_given_ts(actsvr, tm);
|
||||
|
||||
entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,actsvr);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
entry->ats = actsvr;
|
||||
list_add_head(&AtsList, &entry->entry);
|
||||
|
||||
@ -456,6 +458,50 @@ HRESULT deactivate_textservices(void)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CLSID get_textservice_clsid(TfClientId tid)
|
||||
{
|
||||
AtsEntry *ats;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
if (ats->ats->tid == tid)
|
||||
return ats->ats->LanguageProfile.clsid;
|
||||
return GUID_NULL;
|
||||
}
|
||||
|
||||
HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown **sink)
|
||||
{
|
||||
AtsEntry *ats;
|
||||
|
||||
if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
if (ats->ats->tid == tid)
|
||||
{
|
||||
*sink = (IUnknown*)ats->ats->pITfKeyEventSink;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink)
|
||||
{
|
||||
AtsEntry *ats;
|
||||
|
||||
if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
if (ats->ats->tid == tid)
|
||||
{
|
||||
ats->ats->pITfKeyEventSink = (ITfKeyEventSink*)sink;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* MSCTF DllMain
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@
|
||||
<file>documentmgr.c</file>
|
||||
<file>inputprocessor.c</file>
|
||||
<file>msctf.c</file>
|
||||
<file>range.c</file>
|
||||
<file>regsvr.c</file>
|
||||
<file>threadmgr.c</file>
|
||||
<file>version.rc</file>
|
||||
|
@ -24,6 +24,8 @@
|
||||
#define COOKIE_MAGIC_TMSINK 0x0010
|
||||
#define COOKIE_MAGIC_CONTEXTSINK 0x0020
|
||||
#define COOKIE_MAGIC_GUIDATOM 0x0030
|
||||
#define COOKIE_MAGIC_IPPSINK 0x0040
|
||||
#define COOKIE_MAGIC_EDITCOOKIE 0x0050
|
||||
|
||||
extern DWORD tlsIndex;
|
||||
extern TfClientId processId;
|
||||
@ -33,6 +35,10 @@ extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **
|
||||
extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, 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 Context_Initialize(ITfContext *cxt);
|
||||
extern HRESULT Context_Uninitialize(ITfContext *cxt);
|
||||
|
||||
/* cookie function */
|
||||
extern DWORD generate_Cookie(DWORD magic, LPVOID data);
|
||||
@ -47,5 +53,9 @@ extern BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *lp);
|
||||
extern HRESULT activate_textservices(ITfThreadMgr *tm);
|
||||
extern HRESULT deactivate_textservices(void);
|
||||
|
||||
extern CLSID get_textservice_clsid(TfClientId tid);
|
||||
extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sink);
|
||||
extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink);
|
||||
|
||||
extern const WCHAR szwSystemTIPKey[];
|
||||
#endif /* __WINE_MSCTF_I_H */
|
||||
|
333
reactos/dll/win32/msctf/range.c
Normal file
333
reactos/dll/win32/msctf/range.c
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* ITfRange 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 "wine/unicode.h"
|
||||
|
||||
#include "msctf.h"
|
||||
#include "msctf_internal.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msctf);
|
||||
|
||||
typedef struct tagRange {
|
||||
const ITfRangeVtbl *RangeVtbl;
|
||||
/* const ITfRangeACPVtb *RangeACPVtbl; */
|
||||
LONG refCount;
|
||||
|
||||
ITextStoreACP *pITextStoreACP;
|
||||
ITfContext *pITfContext;
|
||||
|
||||
DWORD lockType;
|
||||
TfGravity gravityStart, gravityEnd;
|
||||
DWORD anchorStart, anchorEnd;
|
||||
|
||||
} Range;
|
||||
|
||||
static void Range_Destructor(Range *This)
|
||||
{
|
||||
TRACE("destroying %p\n", This);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_QueryInterface(ITfRange *iface, REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
Range *This = (Range*)iface;
|
||||
*ppvOut = NULL;
|
||||
|
||||
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfRange))
|
||||
{
|
||||
*ppvOut = This;
|
||||
}
|
||||
|
||||
if (*ppvOut)
|
||||
{
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("unsupported interface: %s\n", debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Range_AddRef(ITfRange *iface)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
return InterlockedIncrement(&This->refCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI Range_Release(ITfRange *iface)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
ULONG ret;
|
||||
|
||||
ret = InterlockedDecrement(&This->refCount);
|
||||
if (ret == 0)
|
||||
Range_Destructor(This);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* ITfRange functions
|
||||
*****************************************************/
|
||||
|
||||
static HRESULT WINAPI Range_GetText(ITfRange *iface, TfEditCookie ec,
|
||||
DWORD dwFlags, WCHAR *pchText, ULONG cchMax, ULONG *pcch)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_SetText(ITfRange *iface, TfEditCookie ec,
|
||||
DWORD dwFlags, const WCHAR *pchText, LONG cch)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_GetFormattedText(ITfRange *iface, TfEditCookie ec,
|
||||
IDataObject **ppDataObject)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_GetEmbedded(ITfRange *iface, TfEditCookie ec,
|
||||
REFGUID rguidService, REFIID riid, IUnknown **ppunk)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_InsertEmbedded(ITfRange *iface, TfEditCookie ec,
|
||||
DWORD dwFlags, IDataObject *pDataObject)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftStart(ITfRange *iface, TfEditCookie ec,
|
||||
LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftEnd(ITfRange *iface, TfEditCookie ec,
|
||||
LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftStartToRange(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pRange, TfAnchor aPos)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftEndToRange(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pRange, TfAnchor aPos)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftStartRegion(ITfRange *iface, TfEditCookie ec,
|
||||
TfShiftDir dir, BOOL *pfNoRegion)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_ShiftEndRegion(ITfRange *iface, TfEditCookie ec,
|
||||
TfShiftDir dir, BOOL *pfNoRegion)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_IsEmpty(ITfRange *iface, TfEditCookie ec,
|
||||
BOOL *pfEmpty)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_Collapse(ITfRange *iface, TfEditCookie ec,
|
||||
TfAnchor aPos)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_IsEqualStart(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_IsEqualEnd(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_CompareStart(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pWith, TfAnchor aPos, LONG *plResult)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_CompareEnd(ITfRange *iface, TfEditCookie ec,
|
||||
ITfRange *pWith, TfAnchor aPos, LONG *plResult)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_AdjustForInsert(ITfRange *iface, TfEditCookie ec,
|
||||
ULONG cchInsert, BOOL *pfInsertOk)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_GetGravity(ITfRange *iface,
|
||||
TfGravity *pgStart, TfGravity *pgEnd)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_SetGravity(ITfRange *iface, TfEditCookie ec,
|
||||
TfGravity gStart, TfGravity gEnd)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_Clone(ITfRange *iface, ITfRange **ppClone)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Range_GetContext(ITfRange *iface, ITfContext **ppContext)
|
||||
{
|
||||
Range *This = (Range *)iface;
|
||||
TRACE("(%p)\n",This);
|
||||
if (!ppContext)
|
||||
return E_INVALIDARG;
|
||||
*ppContext = This->pITfContext;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const ITfRangeVtbl Range_RangeVtbl =
|
||||
{
|
||||
Range_QueryInterface,
|
||||
Range_AddRef,
|
||||
Range_Release,
|
||||
|
||||
Range_GetText,
|
||||
Range_SetText,
|
||||
Range_GetFormattedText,
|
||||
Range_GetEmbedded,
|
||||
Range_InsertEmbedded,
|
||||
Range_ShiftStart,
|
||||
Range_ShiftEnd,
|
||||
Range_ShiftStartToRange,
|
||||
Range_ShiftEndToRange,
|
||||
Range_ShiftStartRegion,
|
||||
Range_ShiftEndRegion,
|
||||
Range_IsEmpty,
|
||||
Range_Collapse,
|
||||
Range_IsEqualStart,
|
||||
Range_IsEqualEnd,
|
||||
Range_CompareStart,
|
||||
Range_CompareEnd,
|
||||
Range_AdjustForInsert,
|
||||
Range_GetGravity,
|
||||
Range_SetGravity,
|
||||
Range_Clone,
|
||||
Range_GetContext
|
||||
};
|
||||
|
||||
HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut)
|
||||
{
|
||||
Range *This;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Range));
|
||||
if (This == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
TRACE("(%p) %p %p\n",This, context, textstore);
|
||||
|
||||
This->RangeVtbl= &Range_RangeVtbl;
|
||||
This->refCount = 1;
|
||||
This->pITfContext = context;
|
||||
This->pITextStoreACP = textstore;
|
||||
This->lockType = lockType;
|
||||
This->anchorStart = anchorStart;
|
||||
This->anchorEnd = anchorEnd;
|
||||
|
||||
*ppOut = (ITfRange*)This;
|
||||
TRACE("returning %p\n", This);
|
||||
|
||||
return S_OK;
|
||||
}
|
@ -71,6 +71,11 @@ typedef struct tagACLMulti {
|
||||
const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
|
||||
const ITfMessagePumpVtbl *MessagePumpVtbl;
|
||||
const ITfClientIdVtbl *ClientIdVtbl;
|
||||
/* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
|
||||
/* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
|
||||
/* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
|
||||
/* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
|
||||
/* const ITfSourceSingleVtbl *SourceSingleVtbl; */
|
||||
LONG refCount;
|
||||
|
||||
const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
|
||||
@ -78,6 +83,9 @@ typedef struct tagACLMulti {
|
||||
ITfDocumentMgr *focus;
|
||||
LONG activationCount;
|
||||
|
||||
ITfKeyEventSink *forgroundKeyEventSink;
|
||||
CLSID forgroundTextService;
|
||||
|
||||
struct list CurrentPreservedKeys;
|
||||
|
||||
/* kept as separate lists to reduce unnecessary iterations */
|
||||
@ -434,7 +442,7 @@ static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
|
||||
tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
|
||||
if (!tms)
|
||||
return E_OUTOFMEMORY;
|
||||
if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
|
||||
if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink)))
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,tms);
|
||||
return CONNECT_E_CANNOTCONNECT;
|
||||
@ -509,24 +517,87 @@ static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
|
||||
TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
CLSID textservice;
|
||||
ITfKeyEventSink *check = NULL;
|
||||
|
||||
TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
|
||||
|
||||
if (!tid || !pSink)
|
||||
return E_INVALIDARG;
|
||||
|
||||
textservice = get_textservice_clsid(tid);
|
||||
if (IsEqualCLSID(&GUID_NULL,&textservice))
|
||||
return E_INVALIDARG;
|
||||
|
||||
get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
|
||||
if (check != NULL)
|
||||
return CONNECT_E_ADVISELIMIT;
|
||||
|
||||
if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
|
||||
|
||||
if (fForeground)
|
||||
{
|
||||
if (This->forgroundKeyEventSink)
|
||||
{
|
||||
ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
|
||||
ITfKeyEventSink_Release(This->forgroundKeyEventSink);
|
||||
}
|
||||
ITfKeyEventSink_AddRef(check);
|
||||
ITfKeyEventSink_OnSetFocus(check, TRUE);
|
||||
This->forgroundKeyEventSink = check;
|
||||
This->forgroundTextService = textservice;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
|
||||
TfClientId tid)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
CLSID textservice;
|
||||
ITfKeyEventSink *check = NULL;
|
||||
TRACE("(%p) %x\n",This,tid);
|
||||
|
||||
if (!tid)
|
||||
return E_INVALIDARG;
|
||||
|
||||
textservice = get_textservice_clsid(tid);
|
||||
if (IsEqualCLSID(&GUID_NULL,&textservice))
|
||||
return E_INVALIDARG;
|
||||
|
||||
get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
|
||||
|
||||
if (!check)
|
||||
return CONNECT_E_NOCONNECTION;
|
||||
|
||||
set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
|
||||
ITfKeyEventSink_Release(check);
|
||||
|
||||
if (This->forgroundKeyEventSink == check)
|
||||
{
|
||||
ITfKeyEventSink_Release(This->forgroundKeyEventSink);
|
||||
This->forgroundKeyEventSink = NULL;
|
||||
This->forgroundTextService = GUID_NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
|
||||
CLSID *pclsid)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p) %p\n",This,pclsid);
|
||||
if (!pclsid)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
|
||||
return S_FALSE;
|
||||
|
||||
*pclsid = This->forgroundTextService;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
|
||||
|
Loading…
Reference in New Issue
Block a user