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

  1. #include "private.h"
  2. #include "cicsthkl.h"
  3. #define LANGIDFROMHKL(x) LANGID(LOWORD(HandleToLong(x)))
  4. const CHAR c_szCTFTIPKey[] = "SOFTWARE\\Microsoft\\CTF\\TIP\\";
  5. const CHAR c_szLanguageProfileKey[] = "LanguageProfile\\";
  6. const CHAR c_szSubstitutehKL[] = "SubstituteLayout";
  7. //+------------------------------------------------------------------------
  8. //
  9. // Function: cicsthkl_CLSIDToString
  10. //
  11. // Synopsis: Converts a CLSID to an mbcs string.
  12. //
  13. //-------------------------------------------------------------------------
  14. static const BYTE GuidMap[] = {3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  15. 8, 9, '-', 10, 11, 12, 13, 14, 15};
  16. static const char szDigits[] = "0123456789ABCDEF";
  17. BOOL cicsthkl_CLSIDToStringA(REFGUID refGUID, char *pchA)
  18. {
  19. int i;
  20. char *p = pchA;
  21. const BYTE * pBytes = (const BYTE *) &refGUID;
  22. *p++ = '{';
  23. for (i = 0; i < sizeof(GuidMap); i++)
  24. {
  25. if (GuidMap[i] == '-')
  26. {
  27. *p++ = '-';
  28. }
  29. else
  30. {
  31. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  32. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  33. }
  34. }
  35. *p++ = '}';
  36. *p = '\0';
  37. return TRUE;
  38. }
  39. //+---------------------------------------------------------------------------
  40. //
  41. // cicsthkl_AsciiToNum
  42. //
  43. //----------------------------------------------------------------------------
  44. DWORD cicsthkl_AsciiToNum( char *pszAscii)
  45. {
  46. DWORD dwNum = 0;
  47. for (; *pszAscii; pszAscii++) {
  48. if (*pszAscii >= '0' && *pszAscii <= '9') {
  49. dwNum = (dwNum << 4) | (*pszAscii - '0');
  50. } else if (*pszAscii >= 'A' && *pszAscii <= 'F') {
  51. dwNum = (dwNum << 4) | (*pszAscii - 'A' + 0x000A);
  52. } else if (*pszAscii >= 'a' && *pszAscii <= 'f') {
  53. dwNum = (dwNum << 4) | (*pszAscii - 'a' + 0x000A);
  54. } else {
  55. return (0);
  56. }
  57. }
  58. return (dwNum);
  59. }
  60. //+---------------------------------------------------------------------------
  61. //
  62. // cicsthkl_NumToA
  63. //
  64. //----------------------------------------------------------------------------
  65. void cicsthkl_NumToAscii(DWORD dw, char *psz)
  66. {
  67. int n = 7;
  68. while (n >= 0)
  69. {
  70. BYTE b = (BYTE)(dw >> (n * 4)) & 0x0F;
  71. if (b < 0x0A)
  72. *psz = (char)('0' + b);
  73. else
  74. *psz = (char)('A' + b - 0x0A);
  75. psz++;
  76. n--;
  77. }
  78. *psz = L'\0';
  79. return;
  80. }
  81. //+---------------------------------------------------------------------------
  82. //
  83. // GetSubstituteHKLFromReg
  84. //
  85. //----------------------------------------------------------------------------
  86. HKL GetSubstituteHKLFromReg(REFCLSID rclsid, LANGID langid, REFGUID rguid)
  87. {
  88. HKL hKL = NULL;
  89. CHAR szKey[MAX_PATH];
  90. CHAR szTempStr[64];
  91. StringCchCopyA(szKey, ARRAYSIZE(szKey), c_szCTFTIPKey);
  92. cicsthkl_CLSIDToStringA(rclsid, szTempStr);
  93. StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
  94. StringCchCatA(szKey, ARRAYSIZE(szKey), "\\");
  95. StringCchCatA(szKey, ARRAYSIZE(szKey), c_szLanguageProfileKey);
  96. StringCchPrintfA(szTempStr, ARRAYSIZE(szTempStr), "0x%08x", langid);
  97. StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
  98. StringCchCatA(szKey, ARRAYSIZE(szKey), "\\");
  99. cicsthkl_CLSIDToStringA(rguid, szTempStr);
  100. StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
  101. HKEY hKey = NULL;
  102. LONG lRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
  103. if (lRes == ERROR_SUCCESS)
  104. {
  105. DWORD dwType = NULL;
  106. char szValue[32];
  107. DWORD dwCount = sizeof(szValue);
  108. lRes = RegQueryValueExA(hKey,
  109. (LPTSTR)c_szSubstitutehKL,
  110. NULL,
  111. &dwType,
  112. (LPBYTE)szValue,
  113. &dwCount);
  114. if (lRes == ERROR_SUCCESS)
  115. {
  116. if ((szValue[0] == '0') &&
  117. ((szValue[1] == 'X') || (szValue[1] == 'x')))
  118. hKL = (HKL)IntToPtr(cicsthkl_AsciiToNum(&szValue[2]));
  119. }
  120. RegCloseKey(hKey);
  121. }
  122. return hKL;
  123. }
  124. //----------------------------------------------------------------------------
  125. //
  126. // [in] langid
  127. // langid may be LOWORD of the return value of GetKeyboardLayout(0).
  128. //
  129. // The return value
  130. // It returns NULL hKL
  131. // - if Cicero does not have a focus
  132. // - it there is no keyboard TIP running now
  133. // - it the current keyboard TIP does not have a substitute layout.
  134. //
  135. //----------------------------------------------------------------------------
  136. HRESULT CicGetSubstitueHKL(LANGID langid, HKL *phkl, BOOL fCheckFocus)
  137. {
  138. HRESULT hr;
  139. ITfThreadMgr *ptim;
  140. *phkl = NULL;
  141. if (fCheckFocus)
  142. {
  143. BOOL fFocusInCicero = FALSE;
  144. if (SUCCEEDED(CoCreateInstance( CLSID_TF_ThreadMgr,
  145. NULL,
  146. CLSCTX_INPROC_SERVER,
  147. IID_ITfThreadMgr,
  148. (void **)&ptim))) {
  149. ITfDocumentMgr *pdim;
  150. if (SUCCEEDED(ptim->GetFocus(&pdim)) && pdim)
  151. {
  152. fFocusInCicero = TRUE;
  153. pdim->Release();
  154. }
  155. ptim->Release();
  156. }
  157. if (!fFocusInCicero)
  158. {
  159. //
  160. // Cicero does not have a focus. Try GetKeyboardLayout(0).
  161. //
  162. return S_FALSE;
  163. }
  164. }
  165. HKL hKL = NULL;
  166. ITfInputProcessorProfiles *pPro;
  167. if (SUCCEEDED(hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles,
  168. NULL,
  169. CLSCTX_INPROC_SERVER,
  170. IID_ITfInputProcessorProfiles,
  171. (void **)&pPro ))) {
  172. CLSID clsid;
  173. GUID guid;
  174. ITfInputProcessorProfileSubstituteLayout *pProSubLayout;
  175. if (SUCCEEDED(hr = pPro->GetDefaultLanguageProfile(langid,
  176. GUID_TFCAT_TIP_KEYBOARD,
  177. &clsid,
  178. &guid)))
  179. {
  180. if (!IsEqualGUID(clsid, CLSID_NULL))
  181. {
  182. if (SUCCEEDED(hr = pPro->QueryInterface(IID_ITfInputProcessorProfileSubstituteLayout,
  183. (void **)&pProSubLayout)))
  184. {
  185. hr = pProSubLayout->GetSubstituteKeyboardLayout(clsid,
  186. langid,
  187. guid,
  188. &hKL);
  189. pProSubLayout->Release();
  190. }
  191. else
  192. {
  193. hKL = GetSubstituteHKLFromReg(clsid, langid, guid);
  194. hr = S_OK;
  195. }
  196. }
  197. }
  198. pPro->Release();
  199. }
  200. //
  201. // if hKL is NULL, please get hKL from GetKeybaordLayout(0).
  202. //
  203. *phkl = hKL;
  204. return hr;
  205. }
  206. //----------------------------------------------------------------------------
  207. //
  208. // CicSubstGetKeyboardLayout
  209. //
  210. //----------------------------------------------------------------------------
  211. extern "C" HKL WINAPI CicSubstGetKeyboardLayout(char *pszKLID)
  212. {
  213. HKL hkl = NULL;
  214. HKL hklReal = GetKeyboardLayout(0);
  215. if (SUCCEEDED(CicGetSubstitueHKL(LANGIDFROMHKL(hklReal), &hkl, TRUE)))
  216. {
  217. if (!hkl)
  218. {
  219. hkl = hklReal;
  220. if (pszKLID)
  221. GetKeyboardLayoutName(pszKLID);
  222. }
  223. else
  224. {
  225. if (pszKLID)
  226. cicsthkl_NumToAscii((DWORD)HandleToLong(hkl), pszKLID);
  227. }
  228. }
  229. return hkl;
  230. }
  231. //----------------------------------------------------------------------------
  232. //
  233. // CicSubstGetDefaultKeyboardLayout
  234. //
  235. //----------------------------------------------------------------------------
  236. extern "C" HKL WINAPI CicSubstGetDefaultKeyboardLayout(LANGID langid)
  237. {
  238. HKL hkl = NULL;
  239. CicGetSubstitueHKL(langid, &hkl, FALSE);
  240. return hkl;
  241. }