Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

448 lines
11 KiB

/*++
Copyright (c) 2001, Microsoft Corporation
Module Name:
profile.cpp
Abstract:
This file implements the CicProfiles Class.
Author:
Revision History:
Notes:
--*/
#include "private.h"
#include "profile.h"
//+---------------------------------------------------------------------------
//
// CicProfile::Callbacks
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::ActiveLanguageProfileNotifySinkCallback(
REFGUID rguid,
REFGUID rguidProfile,
BOOL fActivated,
void *pv)
{
DebugMsg(TF_FUNC, TEXT("ActiveLanguageProfileNotifySinkCallback"));
CicProfile* _this = (CicProfile*)pv;
_this->ResetCache();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CicProfile::ctor
// CicProfile::dtor
//
//----------------------------------------------------------------------------
CicProfile::CicProfile()
{
m_ref = 1;
m_profile = NULL;
m_pActiveLanguageProfileNotifySink = NULL;
m_SavedLangId = LANG_NEUTRAL;
m_fActivateThread = FALSE;
ResetCache();
m_cp = CP_ACP;
m_LangID = LANG_NEUTRAL;
m_hKL = 0;
}
CicProfile::~CicProfile()
{
if (m_profile) {
if (m_SavedLangId != LANG_NEUTRAL) {
HRESULT hr = m_profile->ChangeCurrentLanguage(m_SavedLangId);
if (FAILED(hr)) {
DebugMsg(TF_ERROR, TEXT("CicProfile::~CicProfile: failed for ChangeCurrentLanguage"));
}
}
m_profile->Release();
m_profile = NULL;
}
if (m_pActiveLanguageProfileNotifySink) {
m_pActiveLanguageProfileNotifySink->_Unadvise();
m_pActiveLanguageProfileNotifySink->Release();
m_pActiveLanguageProfileNotifySink = NULL;
}
}
//+---------------------------------------------------------------------------
//
// CicProfile::QueryInterface
// CicProfile::AddRef
// CicProfile::Release
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::QueryInterface(
REFIID riid,
void** ppvObj)
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG
CicProfile::AddRef(
)
{
return InterlockedIncrement(&m_ref);
}
ULONG
CicProfile::Release(
)
{
ULONG cr = InterlockedDecrement(&m_ref);
if (cr == 0) {
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// CicProfile::InitProfileInstance
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::InitProfileInstance(
TLS* ptls)
{
HRESULT hr;
hr = TF_CreateInputProcessorProfiles(&m_profile);
if (FAILED(hr)) {
DebugMsg(TF_ERROR, TEXT("CicProfile::InitProfileInstance: failed for CoCreate"));
}
else if (m_pActiveLanguageProfileNotifySink == NULL) {
m_pActiveLanguageProfileNotifySink = new CActiveLanguageProfileNotifySink(CicProfile::ActiveLanguageProfileNotifySinkCallback, this);
if (m_pActiveLanguageProfileNotifySink == NULL) {
DebugMsg(TF_ERROR, TEXT("Couldn't create ActiveLanguageProfileNotifySink!"));
m_profile->Release();
m_profile = NULL;
return E_FAIL;
}
ITfThreadMgr_P* ptim_P = ptls->GetTIM();
if (ptim_P != NULL)
{
m_pActiveLanguageProfileNotifySink->_Advise(ptim_P);
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// CicProfile::Activate
// CicProfile::Deactivate
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::Activate(void)
{
m_fActivateThread = TRUE;
ResetCache();
return S_OK;
}
HRESULT
CicProfile::Deactivate(void)
{
m_fActivateThread = FALSE;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CicProfile::ChangeCurrentKeyboardLayout
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::ChangeCurrentKeyboardLayout(
HKL hKL)
{
HRESULT hr;
LANGID CurrentLangId;
hr = m_profile->GetCurrentLanguage(&CurrentLangId);
if (FAILED(hr)) {
DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for GetCurrentLanguage"));
}
else if (hKL != NULL) {
LANGID LangId = LangIdFromKL(hKL);
if (LangId != CurrentLangId) {
hr = m_profile->ChangeCurrentLanguage(LangId);
if (FAILED(hr)) {
m_SavedLangId = LANG_NEUTRAL;
DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for ChangeCurrentLanguage"));
}
m_SavedLangId = LangId;
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// CicProfile::GetLangId
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::GetLangId(
LANGID *plid)
{
if (!m_profile)
return E_FAIL;
if (!plid)
return E_INVALIDARG;
HRESULT hr = S_OK;
if (m_fInitLangID) {
*plid = m_LangID;
}
else {
*plid = LANG_NEUTRAL;
hr = m_profile->GetCurrentLanguage(plid);
if (FAILED(hr)) {
DebugMsg(TF_ERROR, TEXT("CicProfile::GetLangId: failed for GetCurrentLanguage"));
}
else {
m_LangID = *plid;
m_fInitLangID = TRUE;
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// CicProfile::GetCodePageA
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::GetCodePageA(
UINT *puCodePage
)
{
if (!puCodePage)
return E_INVALIDARG;
if (m_fInitCP) {
*puCodePage = m_cp;
}
else {
*puCodePage = CP_ACP;
LANGID langid;
if (FAILED(GetLangId(&langid)))
return E_FAIL;
WCHAR szCodePage[12];
int ret = GetLocaleInfoW(MAKELCID(langid, SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE,
szCodePage,
sizeof(szCodePage)/sizeof(WCHAR));
if (ret) {
szCodePage[ret] = L'\0';
*puCodePage = wcstoul(szCodePage, NULL, 10);
m_cp = *puCodePage;
m_fInitCP = TRUE;
}
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CicProfile::GetKeyboardLayout
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::GetKeyboardLayout(
HKL* phkl)
{
if (! phkl)
return E_INVALIDARG;
*phkl = NULL;
if (m_fInitHKL) {
*phkl = m_hKL;
}
else if (! m_fActivateThread) {
return E_FAIL;
}
else {
LANGID langid;
GUID guidProfile;
HRESULT hr = m_profile->GetActiveLanguageProfile(GUID_TFCAT_TIP_KEYBOARD,
&langid,
&guidProfile);
if (FAILED(hr))
return hr;
//
// Instead of (!IsEqualGUID(guidProfil, GUID_NULL)), we check
// 2nd, 3r and 4th DWORD of guidProfile. Because
// GetActivelanguageProfile(category guid) may return hKL in
// guidProfile
//
if ((((unsigned long *) &guidProfile)[1] != 0) ||
(((unsigned long *) &guidProfile)[2] != 0) ||
(((unsigned long *) &guidProfile)[3] != 0)) {
/*
* Current keyboard layout is Cicero.
*/
m_hKL = (HKL)LongToHandle(langid); // Don't use ::GetKeyboardLayout(0);
// Cicero awre doesn't case hKL.
}
else if (!IsEqualGUID(guidProfile, GUID_NULL)) {
/*
* Current keyboard layout is regacy IME.
*/
m_hKL = (HKL)LongToHandle(*(DWORD *)&guidProfile);
}
else {
m_hKL = 0;
}
*phkl = m_hKL;
m_fInitHKL = TRUE;
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CicProfile::IsIME
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::IsIME(
HKL hKL)
{
LANGID LangId = LangIdFromKL(hKL);
Interface<IEnumTfLanguageProfiles> LanguageProfiles;
HRESULT hr = m_profile->EnumLanguageProfiles(LangId,
LanguageProfiles);
if (FAILED(hr))
return S_FALSE;
//
// AIMM12 compat.
// we don't set GUID_TFCAT_TIP_KEYBOARD catid to enumerate profiles.
// so if we have some other TIP than Keyboard TIP, we may return S_OK.
//
CEnumrateValue<IEnumTfLanguageProfiles,
TF_LANGUAGEPROFILE,
LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles,
LanguageProfilesCallback);
ENUM_RET ret = Enumrate.DoEnumrate();
if (ret != ENUM_FIND)
return S_FALSE;
else
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CicProfile::GetActiveLanguageProfile
// CicProfile::LanguageProfilesCallback
//
//----------------------------------------------------------------------------
HRESULT
CicProfile::GetActiveLanguageProfile(
IN HKL hKL,
IN GUID catid,
OUT TF_LANGUAGEPROFILE* pLanguageProfile)
{
LANGID LangId = LangIdFromKL(hKL);
Interface<IEnumTfLanguageProfiles> LanguageProfiles;
HRESULT hr = m_profile->EnumLanguageProfiles(LangId,
LanguageProfiles);
if (FAILED(hr))
return S_FALSE;
LANG_PROF_ENUM_ARG LangProfEnumArg;
LangProfEnumArg.catid = catid;
CEnumrateValue<IEnumTfLanguageProfiles,
TF_LANGUAGEPROFILE,
LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles,
LanguageProfilesCallback,
&LangProfEnumArg);
ENUM_RET ret = Enumrate.DoEnumrate();
if (ret != ENUM_FIND || pLanguageProfile == NULL)
return S_FALSE;
else {
*pLanguageProfile = LangProfEnumArg.LanguageProfile;
return S_OK;
}
}
ENUM_RET
CicProfile::LanguageProfilesCallback(
TF_LANGUAGEPROFILE LanguageProfile,
LANG_PROF_ENUM_ARG* pLangProfEnumArg)
{
if (LanguageProfile.fActive &&
! IsEqualGUID(LanguageProfile.clsid, GUID_NULL)) {
if (pLangProfEnumArg) {
if (! IsEqualGUID(LanguageProfile.catid, pLangProfEnumArg->catid)) {
return ENUM_CONTINUE;
}
pLangProfEnumArg->LanguageProfile = LanguageProfile;
}
return ENUM_FIND;
}
return ENUM_CONTINUE;
}