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.
 
 
 
 
 
 

287 lines
8.4 KiB

#include "private.h"
#include "cicsthkl.h"
#define LANGIDFROMHKL(x) LANGID(LOWORD(HandleToLong(x)))
const CHAR c_szCTFTIPKey[] = "SOFTWARE\\Microsoft\\CTF\\TIP\\";
const CHAR c_szLanguageProfileKey[] = "LanguageProfile\\";
const CHAR c_szSubstitutehKL[] = "SubstituteLayout";
//+------------------------------------------------------------------------
//
// Function: cicsthkl_CLSIDToString
//
// Synopsis: Converts a CLSID to an mbcs string.
//
//-------------------------------------------------------------------------
static const BYTE GuidMap[] = {3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
8, 9, '-', 10, 11, 12, 13, 14, 15};
static const char szDigits[] = "0123456789ABCDEF";
BOOL cicsthkl_CLSIDToStringA(REFGUID refGUID, char *pchA)
{
int i;
char *p = pchA;
const BYTE * pBytes = (const BYTE *) &refGUID;
*p++ = '{';
for (i = 0; i < sizeof(GuidMap); i++)
{
if (GuidMap[i] == '-')
{
*p++ = '-';
}
else
{
*p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
*p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
}
}
*p++ = '}';
*p = '\0';
return TRUE;
}
//+---------------------------------------------------------------------------
//
// cicsthkl_AsciiToNum
//
//----------------------------------------------------------------------------
DWORD cicsthkl_AsciiToNum( char *pszAscii)
{
DWORD dwNum = 0;
for (; *pszAscii; pszAscii++) {
if (*pszAscii >= '0' && *pszAscii <= '9') {
dwNum = (dwNum << 4) | (*pszAscii - '0');
} else if (*pszAscii >= 'A' && *pszAscii <= 'F') {
dwNum = (dwNum << 4) | (*pszAscii - 'A' + 0x000A);
} else if (*pszAscii >= 'a' && *pszAscii <= 'f') {
dwNum = (dwNum << 4) | (*pszAscii - 'a' + 0x000A);
} else {
return (0);
}
}
return (dwNum);
}
//+---------------------------------------------------------------------------
//
// cicsthkl_NumToA
//
//----------------------------------------------------------------------------
void cicsthkl_NumToAscii(DWORD dw, char *psz)
{
int n = 7;
while (n >= 0)
{
BYTE b = (BYTE)(dw >> (n * 4)) & 0x0F;
if (b < 0x0A)
*psz = (char)('0' + b);
else
*psz = (char)('A' + b - 0x0A);
psz++;
n--;
}
*psz = L'\0';
return;
}
//+---------------------------------------------------------------------------
//
// GetSubstituteHKLFromReg
//
//----------------------------------------------------------------------------
HKL GetSubstituteHKLFromReg(REFCLSID rclsid, LANGID langid, REFGUID rguid)
{
HKL hKL = NULL;
CHAR szKey[MAX_PATH];
CHAR szTempStr[64];
StringCchCopyA(szKey, ARRAYSIZE(szKey), c_szCTFTIPKey);
cicsthkl_CLSIDToStringA(rclsid, szTempStr);
StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
StringCchCatA(szKey, ARRAYSIZE(szKey), "\\");
StringCchCatA(szKey, ARRAYSIZE(szKey), c_szLanguageProfileKey);
StringCchPrintfA(szTempStr, ARRAYSIZE(szTempStr), "0x%08x", langid);
StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
StringCchCatA(szKey, ARRAYSIZE(szKey), "\\");
cicsthkl_CLSIDToStringA(rguid, szTempStr);
StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
HKEY hKey = NULL;
LONG lRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
if (lRes == ERROR_SUCCESS)
{
DWORD dwType = NULL;
char szValue[32];
DWORD dwCount = sizeof(szValue);
lRes = RegQueryValueExA(hKey,
(LPTSTR)c_szSubstitutehKL,
NULL,
&dwType,
(LPBYTE)szValue,
&dwCount);
if (lRes == ERROR_SUCCESS)
{
if ((szValue[0] == '0') &&
((szValue[1] == 'X') || (szValue[1] == 'x')))
hKL = (HKL)IntToPtr(cicsthkl_AsciiToNum(&szValue[2]));
}
RegCloseKey(hKey);
}
return hKL;
}
//----------------------------------------------------------------------------
//
// [in] langid
// langid may be LOWORD of the return value of GetKeyboardLayout(0).
//
// The return value
// It returns NULL hKL
// - if Cicero does not have a focus
// - it there is no keyboard TIP running now
// - it the current keyboard TIP does not have a substitute layout.
//
//----------------------------------------------------------------------------
HRESULT CicGetSubstitueHKL(LANGID langid, HKL *phkl, BOOL fCheckFocus)
{
HRESULT hr;
ITfThreadMgr *ptim;
*phkl = NULL;
if (fCheckFocus)
{
BOOL fFocusInCicero = FALSE;
if (SUCCEEDED(CoCreateInstance( CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfThreadMgr,
(void **)&ptim))) {
ITfDocumentMgr *pdim;
if (SUCCEEDED(ptim->GetFocus(&pdim)) && pdim)
{
fFocusInCicero = TRUE;
pdim->Release();
}
ptim->Release();
}
if (!fFocusInCicero)
{
//
// Cicero does not have a focus. Try GetKeyboardLayout(0).
//
return S_FALSE;
}
}
HKL hKL = NULL;
ITfInputProcessorProfiles *pPro;
if (SUCCEEDED(hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(void **)&pPro ))) {
CLSID clsid;
GUID guid;
ITfInputProcessorProfileSubstituteLayout *pProSubLayout;
if (SUCCEEDED(hr = pPro->GetDefaultLanguageProfile(langid,
GUID_TFCAT_TIP_KEYBOARD,
&clsid,
&guid)))
{
if (!IsEqualGUID(clsid, CLSID_NULL))
{
if (SUCCEEDED(hr = pPro->QueryInterface(IID_ITfInputProcessorProfileSubstituteLayout,
(void **)&pProSubLayout)))
{
hr = pProSubLayout->GetSubstituteKeyboardLayout(clsid,
langid,
guid,
&hKL);
pProSubLayout->Release();
}
else
{
hKL = GetSubstituteHKLFromReg(clsid, langid, guid);
hr = S_OK;
}
}
}
pPro->Release();
}
//
// if hKL is NULL, please get hKL from GetKeybaordLayout(0).
//
*phkl = hKL;
return hr;
}
//----------------------------------------------------------------------------
//
// CicSubstGetKeyboardLayout
//
//----------------------------------------------------------------------------
extern "C" HKL WINAPI CicSubstGetKeyboardLayout(char *pszKLID)
{
HKL hkl = NULL;
HKL hklReal = GetKeyboardLayout(0);
if (SUCCEEDED(CicGetSubstitueHKL(LANGIDFROMHKL(hklReal), &hkl, TRUE)))
{
if (!hkl)
{
hkl = hklReal;
if (pszKLID)
GetKeyboardLayoutName(pszKLID);
}
else
{
if (pszKLID)
cicsthkl_NumToAscii((DWORD)HandleToLong(hkl), pszKLID);
}
}
return hkl;
}
//----------------------------------------------------------------------------
//
// CicSubstGetDefaultKeyboardLayout
//
//----------------------------------------------------------------------------
extern "C" HKL WINAPI CicSubstGetDefaultKeyboardLayout(LANGID langid)
{
HKL hkl = NULL;
CicGetSubstitueHKL(langid, &hkl, FALSE);
return hkl;
}