|
|
/*++
Copyright (c) 1985 - 1999, Microsoft Corporation
Module Name:
icocb.cpp
Abstract:
This file implements the CInputContextOwnerCallBack Class.
Author:
Revision History:
Notes:
--*/
#include "private.h"
#include "icocb.h"
#include "cime.h"
#include "imeapp.h"
#include "mouse.h"
#include "tsattrs.h"
#include "imtls.h"
#include "a_context.h"
#include "candpos.h"
CInputContextOwnerCallBack::CInputContextOwnerCallBack(LIBTHREAD *pLibTLS ) : CInputContextOwner(ICOwnerSinkCallback, NULL) { m_pMouseSink = NULL;
m_pLibTLS = pLibTLS; }
CInputContextOwnerCallBack::~CInputContextOwnerCallBack( ) { if (m_pMouseSink) { m_pMouseSink->InternalRelease(); m_pMouseSink = NULL; } }
BOOL CInputContextOwnerCallBack::Init() { //
// Create Mouse Sink
//
Assert(!m_pMouseSink);
m_pMouseSink = new CMouseSink; if (m_pMouseSink == NULL) return FALSE;
if (!m_pMouseSink->Init()) { delete m_pMouseSink; m_pMouseSink = NULL; return FALSE; }
return TRUE; }
// static
HRESULT CInputContextOwnerCallBack::ICOwnerSinkCallback( UINT uCode, ICOARGS *pargs, void *pv ) { DebugMsg(TF_FUNC, "ICOwnerSinkCallback");
POINT pt; IMTLS *ptls;
CInputContextOwnerCallBack* _this = (CInputContextOwnerCallBack*)pv;
switch (uCode) { case ICO_POINT_TO_ACP: Assert(0); return E_NOTIMPL;
case ICO_KEYDOWN: case ICO_KEYUP: *pargs->key.pfEaten = FALSE; break;
case ICO_SCREENEXT: { ptls = IMTLS_GetOrAlloc(); if (ptls == NULL) break; IMCLock imc(ptls->hIMC); if (imc.Invalid()) break;
GetClientRect(imc->hWnd, pargs->scr_ext.prc); pt.x = pt.y = 0; ClientToScreen(imc->hWnd, &pt);
pargs->scr_ext.prc->left += pt.x; pargs->scr_ext.prc->right += pt.x; pargs->scr_ext.prc->top += pt.y; pargs->scr_ext.prc->bottom += pt.y; }
break;
case ICO_TEXTEXT: //
// consider.
//
// hack TextExtent from CANDIDATEFORM of HIMC.
//
// more hacks
// - may want to send WM_OPENCANDIDATEPOS to let apps
// call ImmSetCandidateWindow().
// - may need to calculate the actual point from rcArea.
//
{ CCandidatePosition cand_pos; cand_pos.GetCandidatePosition(pargs->text_ext.prc); } break;
case ICO_STATUS: pargs->status.pdcs->dwDynamicFlags = 0; pargs->status.pdcs->dwStaticFlags = TF_SS_TRANSITORY; break;
case ICO_WND: { ptls = IMTLS_GetOrAlloc(); if (ptls == NULL) break; IMCLock imc(ptls->hIMC); *(pargs->hwnd.phwnd) = NULL; if (imc.Invalid()) break;
*(pargs->hwnd.phwnd) = imc->hWnd; } break;
case ICO_ATTR: return _this->GetAttribute(pargs->sys_attr.pguid, pargs->sys_attr.pvar);
case ICO_ADVISEMOUSE: { ptls = IMTLS_GetOrAlloc(); if (ptls == NULL) break; _this->m_pMouseSink->InternalAddRef(); return _this->m_pMouseSink->AdviseMouseSink(ptls->hIMC, pargs->advise_mouse.rangeACP, pargs->advise_mouse.pSink, pargs->advise_mouse.pdwCookie); } break;
case ICO_UNADVISEMOUSE: { HRESULT hr = _this->m_pMouseSink->UnadviseMouseSink(pargs->unadvise_mouse.dwCookie); _this->m_pMouseSink->InternalRelease(); return hr; } break;
default: Assert(0); // shouldn't ever get here
break; }
return S_OK; }
/*++
Method:
CInputContextOwnerCallBack::GetAttribute
Routine Description:
Implementation of ITfContextOwner::GetAttribute. Returns the value of a cicero app property attribute.
Arguments:
pguid - [in] GUID of the attrib in question. pvarValue - [out] VARIANT, receives the value. VT_EMPTY if we don't support it.
Return Value:
Returns S_OK if successful, or an error code otherwise.
--*/
HRESULT CInputContextOwnerCallBack::GetAttribute( const GUID *pguid, VARIANT *pvarValue ) { TfGuidAtom ga; const GUID *pguidValue; IMTLS *ptls;
QuickVariantInit(pvarValue);
ptls = IMTLS_GetOrAlloc(); if (ptls == NULL) return E_FAIL;
if (IsEqualGUID(*pguid, GUID_PROP_MODEBIAS)) { // xlate conversion mode, sentence mode to cicero mode bias
IMCLock imc(ptls->hIMC); if (imc.Invalid()) return E_FAIL;
CAImeContext* _pAImeContext = imc->m_pAImeContext; ASSERT(_pAImeContext != NULL); if (_pAImeContext == NULL) return E_FAIL;
if (_pAImeContext->lModeBias == MODEBIASMODE_FILENAME) { pguidValue = &GUID_MODEBIAS_FILENAME; } else if (_pAImeContext->lModeBias == MODEBIASMODE_DIGIT) { pguidValue = &GUID_MODEBIAS_NUMERIC; } else { if (imc->fdwConversion & IME_CMODE_GUID_NULL) { //
// If extended conversion mode were set on,
// returns GUID_NULL.
// No returns any MODEBIAS.
//
pguidValue = &GUID_NULL; } else
//
// existing logic:
//
// if imcp->lModeBias == MODEBIASMODE_DEFAULT
// IME_SMODE_CONVERSATION -> GUID_MODEBIAS_CONVERSATION
// otherwise -> GUID_MODEBIAS_NONE
// otherwise
// -> MODEBIASMODE_FILENAME -> GUID_MODEBIAS_FILENAME
//
if (_pAImeContext->lModeBias == MODEBIASMODE_DEFAULT) { pguidValue = &GUID_MODEBIAS_NONE;
if (imc->fdwConversion & IME_CMODE_KATAKANA) { if (imc->fdwConversion & IME_CMODE_FULLSHAPE) pguidValue = &GUID_MODEBIAS_KATAKANA; else pguidValue = &GUID_MODEBIAS_HALFWIDTHKATAKANA; } else if (imc->fdwConversion & IME_CMODE_NATIVE) { pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC; LANGID langid; ptls->pAImeProfile->GetLangId(&langid); if (langid == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) { if (imc->fdwConversion & IME_CMODE_FULLSHAPE) pguidValue = &GUID_MODEBIAS_HIRAGANA; else pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC; } else if (langid == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT)) { if (imc->fdwConversion & IME_CMODE_FULLSHAPE) pguidValue = &GUID_MODEBIAS_FULLWIDTHHANGUL; else pguidValue = &GUID_MODEBIAS_HANGUL; } else if (PRIMARYLANGID(langid) == LANG_CHINESE) { pguidValue = &GUID_MODEBIAS_CHINESE; } } else { if (imc->fdwConversion & IME_CMODE_FULLSHAPE) pguidValue = &GUID_MODEBIAS_FULLWIDTHALPHANUMERIC; else pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC; } }
//
// We overwrite modebias here....
//
if (imc->fdwSentence & IME_SMODE_GUID_NULL) { //
// If extended sentence mode were set on,
// returns GUID_NULL.
// No returns any MODEBIAS.
//
// Nothing to do. pguidValue might be changed with CMODE
// pguidValue = &GUID_NULL;
} else if (imc->fdwSentence & IME_SMODE_CONVERSATION) pguidValue = &GUID_MODEBIAS_CONVERSATION; else if (imc->fdwSentence & IME_SMODE_PLAURALCLAUSE) pguidValue = &GUID_MODEBIAS_NAME; }
if (!GetGUIDATOMFromGUID(m_pLibTLS, *pguidValue, &ga)) return E_FAIL;
pvarValue->vt = VT_I4; // for TfGuidAtom
pvarValue->lVal = ga; } if (IsEqualGUID(*pguid, TSATTRID_Text_Orientation)) { // xlate conversion mode, sentence mode to cicero mode bias
IMCLock imc(ptls->hIMC); if (imc.Invalid()) return E_FAIL;
pvarValue->vt = VT_I4; pvarValue->lVal = imc->lfFont.A.lfEscapement; } if (IsEqualGUID(*pguid, TSATTRID_Text_VerticalWriting)) { // xlate conversion mode, sentence mode to cicero mode bias
IMCLock imc(ptls->hIMC); if (imc.Invalid()) return E_FAIL;
LOGFONTW font; if (SUCCEEDED(ptls->pAImm->GetCompositionFontW(ptls->hIMC, &font))) { pvarValue->vt = VT_BOOL; pvarValue->lVal = (imc->lfFont.W.lfFaceName[0] == L'@' ? TRUE : FALSE); } }
return S_OK; }
LRESULT CInputContextOwnerCallBack::MsImeMouseHandler( ULONG uEdge, ULONG uQuadrant, ULONG dwBtnStatus, IMCLock& imc, ImmIfIME* ImmIfIme ) { return m_pMouseSink->MsImeMouseHandler(uEdge, uQuadrant, dwBtnStatus, imc, ImmIfIme); }
|