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

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. profile.cpp
  5. Abstract:
  6. This file implements the CicProfiles Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "profile.h"
  13. //+---------------------------------------------------------------------------
  14. //
  15. // CicProfile::Callbacks
  16. //
  17. //----------------------------------------------------------------------------
  18. HRESULT
  19. CicProfile::ActiveLanguageProfileNotifySinkCallback(
  20. REFGUID rguid,
  21. REFGUID rguidProfile,
  22. BOOL fActivated,
  23. void *pv)
  24. {
  25. DebugMsg(TF_FUNC, TEXT("ActiveLanguageProfileNotifySinkCallback"));
  26. CicProfile* _this = (CicProfile*)pv;
  27. _this->ResetCache();
  28. return S_OK;
  29. }
  30. //+---------------------------------------------------------------------------
  31. //
  32. // CicProfile::ctor
  33. // CicProfile::dtor
  34. //
  35. //----------------------------------------------------------------------------
  36. CicProfile::CicProfile()
  37. {
  38. m_ref = 1;
  39. m_profile = NULL;
  40. m_pActiveLanguageProfileNotifySink = NULL;
  41. m_SavedLangId = LANG_NEUTRAL;
  42. m_fActivateThread = FALSE;
  43. ResetCache();
  44. m_cp = CP_ACP;
  45. m_LangID = LANG_NEUTRAL;
  46. m_hKL = 0;
  47. }
  48. CicProfile::~CicProfile()
  49. {
  50. if (m_profile) {
  51. if (m_SavedLangId != LANG_NEUTRAL) {
  52. HRESULT hr = m_profile->ChangeCurrentLanguage(m_SavedLangId);
  53. if (FAILED(hr)) {
  54. DebugMsg(TF_ERROR, TEXT("CicProfile::~CicProfile: failed for ChangeCurrentLanguage"));
  55. }
  56. }
  57. m_profile->Release();
  58. m_profile = NULL;
  59. }
  60. if (m_pActiveLanguageProfileNotifySink) {
  61. m_pActiveLanguageProfileNotifySink->_Unadvise();
  62. m_pActiveLanguageProfileNotifySink->Release();
  63. m_pActiveLanguageProfileNotifySink = NULL;
  64. }
  65. }
  66. //+---------------------------------------------------------------------------
  67. //
  68. // CicProfile::QueryInterface
  69. // CicProfile::AddRef
  70. // CicProfile::Release
  71. //
  72. //----------------------------------------------------------------------------
  73. HRESULT
  74. CicProfile::QueryInterface(
  75. REFIID riid,
  76. void** ppvObj)
  77. {
  78. *ppvObj = NULL;
  79. return E_NOINTERFACE;
  80. }
  81. ULONG
  82. CicProfile::AddRef(
  83. )
  84. {
  85. return InterlockedIncrement(&m_ref);
  86. }
  87. ULONG
  88. CicProfile::Release(
  89. )
  90. {
  91. ULONG cr = InterlockedDecrement(&m_ref);
  92. if (cr == 0) {
  93. delete this;
  94. }
  95. return cr;
  96. }
  97. //+---------------------------------------------------------------------------
  98. //
  99. // CicProfile::InitProfileInstance
  100. //
  101. //----------------------------------------------------------------------------
  102. HRESULT
  103. CicProfile::InitProfileInstance(
  104. TLS* ptls)
  105. {
  106. HRESULT hr;
  107. hr = TF_CreateInputProcessorProfiles(&m_profile);
  108. if (FAILED(hr)) {
  109. DebugMsg(TF_ERROR, TEXT("CicProfile::InitProfileInstance: failed for CoCreate"));
  110. }
  111. else if (m_pActiveLanguageProfileNotifySink == NULL) {
  112. m_pActiveLanguageProfileNotifySink = new CActiveLanguageProfileNotifySink(CicProfile::ActiveLanguageProfileNotifySinkCallback, this);
  113. if (m_pActiveLanguageProfileNotifySink == NULL) {
  114. DebugMsg(TF_ERROR, TEXT("Couldn't create ActiveLanguageProfileNotifySink!"));
  115. m_profile->Release();
  116. m_profile = NULL;
  117. return E_FAIL;
  118. }
  119. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  120. if (ptim_P != NULL)
  121. {
  122. m_pActiveLanguageProfileNotifySink->_Advise(ptim_P);
  123. }
  124. }
  125. return hr;
  126. }
  127. //+---------------------------------------------------------------------------
  128. //
  129. // CicProfile::Activate
  130. // CicProfile::Deactivate
  131. //
  132. //----------------------------------------------------------------------------
  133. HRESULT
  134. CicProfile::Activate(void)
  135. {
  136. m_fActivateThread = TRUE;
  137. ResetCache();
  138. return S_OK;
  139. }
  140. HRESULT
  141. CicProfile::Deactivate(void)
  142. {
  143. m_fActivateThread = FALSE;
  144. return S_OK;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // CicProfile::ChangeCurrentKeyboardLayout
  149. //
  150. //----------------------------------------------------------------------------
  151. HRESULT
  152. CicProfile::ChangeCurrentKeyboardLayout(
  153. HKL hKL)
  154. {
  155. HRESULT hr;
  156. LANGID CurrentLangId;
  157. hr = m_profile->GetCurrentLanguage(&CurrentLangId);
  158. if (FAILED(hr)) {
  159. DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for GetCurrentLanguage"));
  160. }
  161. else if (hKL != NULL) {
  162. LANGID LangId = LangIdFromKL(hKL);
  163. if (LangId != CurrentLangId) {
  164. hr = m_profile->ChangeCurrentLanguage(LangId);
  165. if (FAILED(hr)) {
  166. m_SavedLangId = LANG_NEUTRAL;
  167. DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for ChangeCurrentLanguage"));
  168. }
  169. m_SavedLangId = LangId;
  170. }
  171. }
  172. return hr;
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // CicProfile::GetLangId
  177. //
  178. //----------------------------------------------------------------------------
  179. HRESULT
  180. CicProfile::GetLangId(
  181. LANGID *plid)
  182. {
  183. if (!m_profile)
  184. return E_FAIL;
  185. if (!plid)
  186. return E_INVALIDARG;
  187. HRESULT hr = S_OK;
  188. if (m_fInitLangID) {
  189. *plid = m_LangID;
  190. }
  191. else {
  192. *plid = LANG_NEUTRAL;
  193. hr = m_profile->GetCurrentLanguage(plid);
  194. if (FAILED(hr)) {
  195. DebugMsg(TF_ERROR, TEXT("CicProfile::GetLangId: failed for GetCurrentLanguage"));
  196. }
  197. else {
  198. m_LangID = *plid;
  199. m_fInitLangID = TRUE;
  200. }
  201. }
  202. return hr;
  203. }
  204. //+---------------------------------------------------------------------------
  205. //
  206. // CicProfile::GetCodePageA
  207. //
  208. //----------------------------------------------------------------------------
  209. HRESULT
  210. CicProfile::GetCodePageA(
  211. UINT *puCodePage
  212. )
  213. {
  214. if (!puCodePage)
  215. return E_INVALIDARG;
  216. if (m_fInitCP) {
  217. *puCodePage = m_cp;
  218. }
  219. else {
  220. *puCodePage = CP_ACP;
  221. LANGID langid;
  222. if (FAILED(GetLangId(&langid)))
  223. return E_FAIL;
  224. WCHAR szCodePage[12];
  225. int ret = GetLocaleInfoW(MAKELCID(langid, SORT_DEFAULT),
  226. LOCALE_IDEFAULTANSICODEPAGE,
  227. szCodePage,
  228. sizeof(szCodePage)/sizeof(WCHAR));
  229. if (ret) {
  230. szCodePage[ret] = L'\0';
  231. *puCodePage = wcstoul(szCodePage, NULL, 10);
  232. m_cp = *puCodePage;
  233. m_fInitCP = TRUE;
  234. }
  235. }
  236. return S_OK;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // CicProfile::GetKeyboardLayout
  241. //
  242. //----------------------------------------------------------------------------
  243. HRESULT
  244. CicProfile::GetKeyboardLayout(
  245. HKL* phkl)
  246. {
  247. if (! phkl)
  248. return E_INVALIDARG;
  249. *phkl = NULL;
  250. if (m_fInitHKL) {
  251. *phkl = m_hKL;
  252. }
  253. else if (! m_fActivateThread) {
  254. return E_FAIL;
  255. }
  256. else {
  257. LANGID langid;
  258. GUID guidProfile;
  259. HRESULT hr = m_profile->GetActiveLanguageProfile(GUID_TFCAT_TIP_KEYBOARD,
  260. &langid,
  261. &guidProfile);
  262. if (FAILED(hr))
  263. return hr;
  264. //
  265. // Instead of (!IsEqualGUID(guidProfil, GUID_NULL)), we check
  266. // 2nd, 3r and 4th DWORD of guidProfile. Because
  267. // GetActivelanguageProfile(category guid) may return hKL in
  268. // guidProfile
  269. //
  270. if ((((unsigned long *) &guidProfile)[1] != 0) ||
  271. (((unsigned long *) &guidProfile)[2] != 0) ||
  272. (((unsigned long *) &guidProfile)[3] != 0)) {
  273. /*
  274. * Current keyboard layout is Cicero.
  275. */
  276. m_hKL = (HKL)LongToHandle(langid); // Don't use ::GetKeyboardLayout(0);
  277. // Cicero awre doesn't case hKL.
  278. }
  279. else if (!IsEqualGUID(guidProfile, GUID_NULL)) {
  280. /*
  281. * Current keyboard layout is regacy IME.
  282. */
  283. m_hKL = (HKL)LongToHandle(*(DWORD *)&guidProfile);
  284. }
  285. else {
  286. m_hKL = 0;
  287. }
  288. *phkl = m_hKL;
  289. m_fInitHKL = TRUE;
  290. }
  291. return S_OK;
  292. }
  293. //+---------------------------------------------------------------------------
  294. //
  295. // CicProfile::IsIME
  296. //
  297. //----------------------------------------------------------------------------
  298. HRESULT
  299. CicProfile::IsIME(
  300. HKL hKL)
  301. {
  302. LANGID LangId = LangIdFromKL(hKL);
  303. Interface<IEnumTfLanguageProfiles> LanguageProfiles;
  304. HRESULT hr = m_profile->EnumLanguageProfiles(LangId,
  305. LanguageProfiles);
  306. if (FAILED(hr))
  307. return S_FALSE;
  308. //
  309. // AIMM12 compat.
  310. // we don't set GUID_TFCAT_TIP_KEYBOARD catid to enumerate profiles.
  311. // so if we have some other TIP than Keyboard TIP, we may return S_OK.
  312. //
  313. CEnumrateValue<IEnumTfLanguageProfiles,
  314. TF_LANGUAGEPROFILE,
  315. LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles,
  316. LanguageProfilesCallback);
  317. ENUM_RET ret = Enumrate.DoEnumrate();
  318. if (ret != ENUM_FIND)
  319. return S_FALSE;
  320. else
  321. return S_OK;
  322. }
  323. //+---------------------------------------------------------------------------
  324. //
  325. // CicProfile::GetActiveLanguageProfile
  326. // CicProfile::LanguageProfilesCallback
  327. //
  328. //----------------------------------------------------------------------------
  329. HRESULT
  330. CicProfile::GetActiveLanguageProfile(
  331. IN HKL hKL,
  332. IN GUID catid,
  333. OUT TF_LANGUAGEPROFILE* pLanguageProfile)
  334. {
  335. LANGID LangId = LangIdFromKL(hKL);
  336. Interface<IEnumTfLanguageProfiles> LanguageProfiles;
  337. HRESULT hr = m_profile->EnumLanguageProfiles(LangId,
  338. LanguageProfiles);
  339. if (FAILED(hr))
  340. return S_FALSE;
  341. LANG_PROF_ENUM_ARG LangProfEnumArg;
  342. LangProfEnumArg.catid = catid;
  343. CEnumrateValue<IEnumTfLanguageProfiles,
  344. TF_LANGUAGEPROFILE,
  345. LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles,
  346. LanguageProfilesCallback,
  347. &LangProfEnumArg);
  348. ENUM_RET ret = Enumrate.DoEnumrate();
  349. if (ret != ENUM_FIND || pLanguageProfile == NULL)
  350. return S_FALSE;
  351. else {
  352. *pLanguageProfile = LangProfEnumArg.LanguageProfile;
  353. return S_OK;
  354. }
  355. }
  356. ENUM_RET
  357. CicProfile::LanguageProfilesCallback(
  358. TF_LANGUAGEPROFILE LanguageProfile,
  359. LANG_PROF_ENUM_ARG* pLangProfEnumArg)
  360. {
  361. if (LanguageProfile.fActive &&
  362. ! IsEqualGUID(LanguageProfile.clsid, GUID_NULL)) {
  363. if (pLangProfEnumArg) {
  364. if (! IsEqualGUID(LanguageProfile.catid, pLangProfEnumArg->catid)) {
  365. return ENUM_CONTINUE;
  366. }
  367. pLangProfEnumArg->LanguageProfile = LanguageProfile;
  368. }
  369. return ENUM_FIND;
  370. }
  371. return ENUM_CONTINUE;
  372. }