Source code of Windows XP (NT5)
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.

798 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. DDIS.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #include "imerc.h"
  11. #if defined(UNIIME)
  12. #include "uniime.h"
  13. #endif
  14. /**********************************************************************/
  15. /* ImeInquire() / UniImeInquire() */
  16. /* Return Value: */
  17. /* TRUE - successful, FALSE - failure */
  18. /**********************************************************************/
  19. // initialized data structure of IME
  20. #if defined(UNIIME)
  21. BOOL WINAPI UniImeInquire(
  22. LPINSTDATAL lpInstL,
  23. LPIMEL lpImeL,
  24. #else
  25. BOOL WINAPI ImeInquire(
  26. #endif
  27. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  28. LPTSTR lpszWndCls, // the class name of UI
  29. DWORD dwSystemInfoFlags)
  30. {
  31. if (!lpImeInfo) {
  32. return (FALSE);
  33. }
  34. lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
  35. lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|
  36. #if defined(UNICODE)
  37. IME_PROP_UNICODE|
  38. #endif
  39. #if !defined(DAYI)
  40. IME_PROP_CANDLIST_START_FROM_1|
  41. #endif
  42. IME_PROP_NEED_ALTKEY|IME_PROP_IGNORE_UPKEYS;
  43. lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|
  44. #if !defined(ROMANIME)
  45. #if !defined(WINAR30)
  46. IME_CMODE_SOFTKBD|
  47. #endif
  48. #if !defined(WINIME) && !defined(UNICDIME)
  49. IME_CMODE_EUDC|
  50. #endif
  51. #endif
  52. IME_CMODE_NOCONVERSION;
  53. #if defined(ROMANIME)
  54. lpImeInfo->fdwSentenceCaps = 0;
  55. lpImeInfo->fdwSCSCaps = 0;
  56. lpImeInfo->fdwUICaps = UI_CAP_ROT90;
  57. #else
  58. lpImeInfo->fdwSentenceCaps = IME_SMODE_PHRASEPREDICT;
  59. // composition string is the reading string for simple IME
  60. lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD;
  61. // IME will have different distance base multiple of 900 escapement
  62. #if defined(WINAR30)
  63. // if an IME want to draw soft keyboard by itself, it also can set this
  64. // off
  65. lpImeInfo->fdwUICaps = UI_CAP_ROT90;
  66. #else
  67. lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD;
  68. #endif
  69. #endif
  70. // IME want to decide conversion mode on ImeSelect
  71. lpImeInfo->fdwSelectCaps = (DWORD) 0;
  72. lstrcpy(lpszWndCls, lpImeL->szUIClassName);
  73. return (TRUE);
  74. }
  75. /**********************************************************************/
  76. /* ImeDestroy() / UniImeDestroy */
  77. /* Return Value: */
  78. /* TRUE - successful, FALSE - failure */
  79. /**********************************************************************/
  80. // this dll is unloaded
  81. #if defined(UNIIME)
  82. BOOL WINAPI UniImeDestroy(
  83. LPINSTDATAL lpInstL,
  84. LPIMEL lpImeL,
  85. #else
  86. BOOL WINAPI ImeDestroy(
  87. #endif
  88. UINT uReserved)
  89. {
  90. if (uReserved) {
  91. return (FALSE);
  92. }
  93. #if !defined(ROMANIME)
  94. // free the IME table or data base
  95. FreeTable(lpInstL);
  96. #endif
  97. return (TRUE);
  98. }
  99. /**********************************************************************/
  100. /* InitCompStr() */
  101. /**********************************************************************/
  102. void PASCAL InitCompStr( // init setting for composing string
  103. LPCOMPOSITIONSTRING lpCompStr)
  104. {
  105. if (!lpCompStr) {
  106. return;
  107. }
  108. lpCompStr->dwCompReadAttrLen = 0;
  109. lpCompStr->dwCompReadClauseLen = 0;
  110. lpCompStr->dwCompReadStrLen = 0;
  111. lpCompStr->dwCompAttrLen = 0;
  112. lpCompStr->dwCompClauseLen = 0;
  113. lpCompStr->dwCompStrLen = 0;
  114. lpCompStr->dwCursorPos = 0;
  115. lpCompStr->dwDeltaStart = 0;
  116. lpCompStr->dwResultReadClauseLen = 0;
  117. lpCompStr->dwResultReadStrLen = 0;
  118. lpCompStr->dwResultClauseLen = 0;
  119. lpCompStr->dwResultStrLen = 0;
  120. return;
  121. }
  122. /**********************************************************************/
  123. /* ClearCompStr() */
  124. /* Return Value: */
  125. /* TRUE - successful, FALSE - failure */
  126. /**********************************************************************/
  127. #define NMAXKEY 8
  128. BOOL PASCAL ClearCompStr(
  129. #if defined(UNIIME)
  130. LPIMEL lpImeL,
  131. #endif
  132. LPINPUTCONTEXT lpIMC)
  133. {
  134. HIMCC hMem;
  135. LPCOMPOSITIONSTRING lpCompStr;
  136. DWORD dwSize;
  137. LPBYTE lpbAttr;
  138. UINT i;
  139. LPDWORD lpdwClause;
  140. LPWSTR lpwStr;
  141. if (!lpIMC) {
  142. return (FALSE);
  143. }
  144. dwSize =
  145. // header length
  146. sizeof(COMPOSITIONSTRING) +
  147. // composition reading attribute plus NULL terminator
  148. NMAXKEY * sizeof(WCHAR) / sizeof(TCHAR) + sizeof(DWORD) +
  149. // composition reading clause
  150. sizeof(DWORD) + sizeof(DWORD) +
  151. // composition reading string plus NULL terminator
  152. NMAXKEY * sizeof(WCHAR) + sizeof(DWORD) +
  153. // result reading clause
  154. sizeof(DWORD) + sizeof(DWORD) +
  155. // result reading string plus NULL terminateor
  156. NMAXKEY * sizeof(WCHAR) + sizeof(DWORD) +
  157. // result clause
  158. sizeof(DWORD) + sizeof(DWORD) +
  159. // result string plus NULL terminateor
  160. MAXSTRLEN * sizeof(WCHAR) + sizeof(DWORD);
  161. if (!lpIMC->hCompStr) {
  162. // it maybe free by other IME, init it
  163. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  164. } else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) {
  165. lpIMC->hCompStr = hMem;
  166. } else {
  167. ImmDestroyIMCC(lpIMC->hCompStr);
  168. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  169. return (FALSE);
  170. }
  171. if (!lpIMC->hCompStr) {
  172. return (FALSE);
  173. }
  174. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  175. if (!lpCompStr) {
  176. ImmDestroyIMCC(lpIMC->hCompStr);
  177. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  178. return (FALSE);
  179. }
  180. lpCompStr->dwSize = dwSize;
  181. // 1. composition (reading) string - simple IME
  182. // 2. result reading string
  183. // 3. result string
  184. lpCompStr->dwCompReadAttrLen = 0;
  185. lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING);
  186. lpbAttr = (LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset;
  187. for (i = 0; i < NMAXKEY * sizeof(WCHAR) / sizeof(TCHAR); i++) {
  188. // for simple IMEs, we have no way to reconvert it
  189. *lpbAttr++ = ATTR_TARGET_CONVERTED;
  190. }
  191. *(LPDWORD)lpbAttr = 0;
  192. lpCompStr->dwCompReadClauseLen = 0;
  193. lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset +
  194. NMAXKEY * sizeof(WCHAR) / sizeof(TCHAR) + sizeof(DWORD);
  195. lpdwClause = (LPDWORD)((LPBYTE)lpCompStr +
  196. lpCompStr->dwCompReadClauseOffset);
  197. // clause start from 0
  198. *lpdwClause++ = 0;
  199. // clause length is 0
  200. *lpdwClause = 0;
  201. lpCompStr->dwCompReadStrLen = 0;
  202. lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset +
  203. sizeof(DWORD) + sizeof(DWORD);
  204. // clean up the composition reading string
  205. lpwStr = (LPWSTR)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset);
  206. for (i = 0; i < NMAXKEY; i++) {
  207. *lpwStr++ = 0;
  208. }
  209. *(LPDWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset +
  210. NMAXKEY * sizeof(WCHAR)) = 0;
  211. // composition string is the same with composition reading string
  212. // for simple IMEs
  213. lpCompStr->dwCompAttrLen = 0;
  214. lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset;
  215. lpCompStr->dwCompClauseLen = 0;
  216. lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset;
  217. lpCompStr->dwCompStrLen = 0;
  218. lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset;
  219. lpCompStr->dwCursorPos = 0;
  220. lpCompStr->dwDeltaStart = 0;
  221. lpCompStr->dwResultReadClauseLen = 0;
  222. lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset +
  223. NMAXKEY * sizeof(WCHAR) + sizeof(DWORD);
  224. lpdwClause = (LPDWORD)((LPBYTE)lpCompStr +
  225. lpCompStr->dwResultReadClauseOffset);
  226. // clause start from 0
  227. *lpdwClause++ = 0;
  228. // clause length is 0
  229. *lpdwClause = 0;
  230. lpCompStr->dwResultReadStrLen = 0;
  231. lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset +
  232. sizeof(DWORD) + sizeof(DWORD);
  233. // clean up the result reading string
  234. lpwStr = (LPWSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultReadStrOffset);
  235. for (i = 0; i < NMAXKEY; i++) {
  236. *lpwStr++ = 0;
  237. }
  238. *(LPDWORD)((LPBYTE)lpCompStr + lpCompStr->dwResultReadStrOffset +
  239. NMAXKEY * sizeof(WCHAR)) = 0;
  240. lpCompStr->dwResultClauseLen = 0;
  241. lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset +
  242. NMAXKEY * sizeof(WCHAR) + sizeof(DWORD);
  243. lpdwClause = (LPDWORD)((LPBYTE)lpCompStr +
  244. lpCompStr->dwResultClauseOffset);
  245. // clause start from 0
  246. *lpdwClause++ = 0;
  247. // clause length is 0
  248. *lpdwClause = 0;
  249. lpCompStr->dwResultStrOffset = 0;
  250. lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset +
  251. sizeof(DWORD) + sizeof(DWORD);
  252. // clean up the result string
  253. lpwStr = (LPWSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset);
  254. for (i = 0; i < NMAXKEY; i++) {
  255. *lpwStr++ = 0;
  256. }
  257. *(LPDWORD)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset +
  258. NMAXKEY * sizeof(WCHAR)) = 0;
  259. ImmUnlockIMCC(lpIMC->hCompStr);
  260. return (TRUE);
  261. }
  262. /**********************************************************************/
  263. /* ClearCand() */
  264. /* Return Value: */
  265. /* TRUE - successful, FALSE - failure */
  266. /**********************************************************************/
  267. BOOL PASCAL ClearCand(
  268. LPINPUTCONTEXT lpIMC)
  269. {
  270. HIMCC hMem;
  271. LPCANDIDATEINFO lpCandInfo;
  272. LPCANDIDATELIST lpCandList;
  273. DWORD dwSize =
  274. // header length
  275. sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) +
  276. // candidate string pointers
  277. sizeof(DWORD) * (MAXCAND) +
  278. // string plus NULL terminator
  279. (sizeof(WCHAR) + sizeof(TCHAR)) * MAXCAND;
  280. if (!lpIMC) {
  281. return (FALSE);
  282. }
  283. if (!lpIMC->hCandInfo) {
  284. // it maybe free by other IME, init it
  285. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  286. } else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) {
  287. lpIMC->hCandInfo = hMem;
  288. } else {
  289. ImmDestroyIMCC(lpIMC->hCandInfo);
  290. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  291. return (FALSE);
  292. }
  293. if (!lpIMC->hCandInfo) {
  294. return (FALSE);
  295. }
  296. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  297. if (!lpCandInfo) {
  298. ImmDestroyIMCC(lpIMC->hCandInfo);
  299. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  300. return (FALSE);
  301. }
  302. // ordering of strings are
  303. // buffer size
  304. lpCandInfo->dwSize = dwSize;
  305. lpCandInfo->dwCount = 0;
  306. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  307. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  308. lpCandInfo->dwOffset[0]);
  309. // whole candidate info size - header
  310. lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO);
  311. lpCandList->dwStyle = IME_CAND_READ;
  312. lpCandList->dwCount = 0;
  313. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  314. lpCandList->dwPageSize = CANDPERPAGE;
  315. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) +
  316. sizeof(DWORD) * (MAXCAND - 1);
  317. ImmUnlockIMCC(lpIMC->hCandInfo);
  318. return (TRUE);
  319. }
  320. /**********************************************************************/
  321. /* InitGuideLine() */
  322. /**********************************************************************/
  323. void PASCAL InitGuideLine( // init guide line
  324. LPGUIDELINE lpGuideLine)
  325. {
  326. #if !defined(ROMANIME)
  327. LPCANDIDATELIST lpCandList;
  328. #endif
  329. if (!lpGuideLine) {
  330. return;
  331. }
  332. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  333. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  334. lpGuideLine->dwStrLen = 0;
  335. lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
  336. lpGuideLine->dwPrivateOffset = sizeof(GUIDELINE);
  337. #if defined(ROMANIME)
  338. lpGuideLine->dwPrivateSize = sizeof(lpGuideLine->dwPrivateSize) +
  339. sizeof(lpGuideLine->dwPrivateOffset);
  340. #else
  341. lpGuideLine->dwPrivateSize = lpGuideLine->dwSize - sizeof(GUIDELINE) -
  342. sizeof(lpGuideLine->dwPrivateSize) -
  343. sizeof(lpGuideLine->dwPrivateOffset);
  344. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpGuideLine +
  345. lpGuideLine->dwPrivateOffset);
  346. lpCandList->dwSize = lpGuideLine->dwSize - sizeof(GUIDELINE);
  347. lpCandList->dwStyle = IME_CAND_READ;
  348. lpCandList->dwCount = 0;
  349. lpCandList->dwSelection = 0;
  350. lpCandList->dwPageSize = CANDPERPAGE;
  351. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
  352. (MAX_COMP_BUF - 1);
  353. #endif
  354. return;
  355. }
  356. /**********************************************************************/
  357. /* ClearGuideLine() */
  358. /* Return Value: */
  359. /* TRUE - successful, FALSE - failure */
  360. /**********************************************************************/
  361. BOOL PASCAL ClearGuideLine(
  362. #if defined(UNIIME)
  363. LPIMEL lpImeL,
  364. #endif
  365. LPINPUTCONTEXT lpIMC)
  366. {
  367. HIMCC hMem;
  368. LPGUIDELINE lpGuideLine;
  369. DWORD dwSize =
  370. // header length
  371. sizeof(GUIDELINE) +
  372. // string for status error
  373. #if defined(ROMANIME)
  374. 0;
  375. #else
  376. // private header length
  377. sizeof(CANDIDATELIST) +
  378. // candidate string pointers
  379. sizeof(DWORD) * MAX_COMP_BUF +
  380. // string plus NULL terminator
  381. (sizeof(WCHAR) * lpImeL->nRevMaxKey + sizeof(TCHAR)) * MAX_COMP_BUF;
  382. #endif
  383. if (!lpIMC->hGuideLine) {
  384. // it maybe free by IME
  385. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  386. } else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) {
  387. lpIMC->hGuideLine = hMem;
  388. } else {
  389. ImmDestroyIMCC(lpIMC->hGuideLine);
  390. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  391. }
  392. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  393. if (!lpGuideLine) {
  394. return (FALSE);
  395. }
  396. lpGuideLine->dwSize = dwSize;
  397. InitGuideLine(lpGuideLine);
  398. ImmUnlockIMCC(lpIMC->hGuideLine);
  399. return (TRUE);
  400. }
  401. /**********************************************************************/
  402. /* InitContext() */
  403. /**********************************************************************/
  404. void PASCAL InitContext(
  405. #if defined(UNIIME)
  406. LPIMEL lpImeL,
  407. #endif
  408. LPINPUTCONTEXT lpIMC,
  409. LPPRIVCONTEXT lpImcP)
  410. {
  411. if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
  412. } else if (!lpIMC->hWnd) {
  413. #if 0 // MultiMonitor support
  414. } else if (lpImcP->fdwInit & INIT_STATUSWNDPOS) {
  415. #endif
  416. } else {
  417. #if 0 // MultiMonitor support
  418. POINT ptWnd;
  419. ptWnd.x = 0;
  420. ptWnd.y = 0;
  421. ClientToScreen(lpIMC->hWnd, &ptWnd);
  422. if (ptWnd.x > sImeG.rcWorkArea.right / 3) {
  423. ptWnd.x = sImeG.rcWorkArea.right / 3;
  424. }
  425. if (ptWnd.x < sImeG.rcWorkArea.left) {
  426. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
  427. } else if (ptWnd.x + lpImeL->xStatusWi > sImeG.rcWorkArea.right) {
  428. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
  429. lpImeL->xStatusWi;
  430. } else {
  431. lpIMC->ptStatusWndPos.x = ptWnd.x;
  432. }
  433. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  434. lpImeL->yStatusHi - 2 * UI_MARGIN;
  435. lpImcP->fdwInit |= INIT_STATUSWNDPOS;
  436. #else
  437. RECT rcWorkArea;
  438. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  439. lpIMC->ptStatusWndPos.x = rcWorkArea.left + 2 * UI_MARGIN;
  440. lpIMC->ptStatusWndPos.y = rcWorkArea.bottom -
  441. lpImeL->yStatusHi - 2 * UI_MARGIN;
  442. #endif
  443. }
  444. #if !defined(ROMANIME)
  445. if (!(lpIMC->fdwInit & INIT_COMPFORM)) {
  446. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  447. }
  448. if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
  449. } else if (!lpIMC->hWnd) {
  450. } else if (lpImcP->fdwInit & INIT_COMPFORM) {
  451. } else {
  452. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  453. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
  454. lpImeL->rcStatusText.right + lpImeL->cxCompBorder * 2 +
  455. UI_MARGIN;
  456. if (lpIMC->cfCompForm.ptCurrentPos.x + (lpImeL->nRevMaxKey *
  457. sImeG.xChiCharWi) > sImeG.rcWorkArea.right) {
  458. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
  459. lpImeL->nRevMaxKey * sImeG.xChiCharWi -
  460. lpImeL->cxCompBorder * 3;
  461. }
  462. } else {
  463. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
  464. lpImeL->xStatusWi + UI_MARGIN;
  465. if (lpIMC->cfCompForm.ptCurrentPos.x + lpImeL->xCompWi >
  466. sImeG.rcWorkArea.right) {
  467. lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
  468. lpImeL->xCompWi - lpImeL->cxCompBorder * 2 -
  469. UI_MARGIN;
  470. }
  471. }
  472. lpIMC->cfCompForm.ptCurrentPos.y = sImeG.rcWorkArea.bottom -
  473. lpImeL->yCompHi - 2 * UI_MARGIN;
  474. ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
  475. lpImcP->fdwInit |= INIT_COMPFORM;
  476. }
  477. #endif
  478. return;
  479. }
  480. /**********************************************************************/
  481. /* Select() */
  482. /* Return Value: */
  483. /* TRUE - successful, FALSE - failure */
  484. /**********************************************************************/
  485. BOOL PASCAL Select(
  486. #if defined(UNIIME)
  487. LPIMEL lpImeL,
  488. #endif
  489. LPINPUTCONTEXT lpIMC,
  490. BOOL fSelect)
  491. {
  492. LPPRIVCONTEXT lpImcP;
  493. if (fSelect) { // init "every" fields of hPrivate, please!!!
  494. if (!ClearCompStr(
  495. #if defined(UNIIME)
  496. lpImeL,
  497. #endif
  498. lpIMC)) {
  499. return (FALSE);
  500. }
  501. if (!ClearCand(lpIMC)) {
  502. return (FALSE);
  503. }
  504. ClearGuideLine(
  505. #if defined(UNIIME)
  506. lpImeL,
  507. #endif
  508. lpIMC);
  509. }
  510. if (lpIMC->cfCandForm[0].dwIndex != 0) {
  511. lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
  512. }
  513. // We add this hack for switching from other IMEs, this IME has a bug.
  514. // Before this bug fixed in this IME, it depends on this hack.
  515. if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) {
  516. lpIMC->cfCandForm[0].dwIndex = (DWORD)-1;
  517. }
  518. if (!lpIMC->hPrivate) {
  519. return (FALSE);
  520. }
  521. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  522. if (!lpImcP) {
  523. return (FALSE);
  524. }
  525. if (fSelect) { // init "every" fields of hPrivate, please!!!
  526. #if !defined(ROMANIME)
  527. lpImcP->iImeState = CST_INIT; // init the IME state machine
  528. lpImcP->fdwImeMsg = 0; // no message be generated now
  529. lpImcP->dwCompChar = 0;
  530. lpImcP->fdwGcsFlag = 0;
  531. lpImcP->fdwInit = 0;
  532. *(LPDWORD)lpImcP->bSeq = 0;
  533. #if defined(CHAJEI) || defined(QUICK) || defined(WINAR30) || defined(UNIIME)
  534. *(LPDWORD)&lpImcP->bSeq[4] = 0;
  535. #endif
  536. #endif
  537. lpIMC->fOpen = TRUE;
  538. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  539. lpIMC->fdwConversion = (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) |
  540. IME_CMODE_NATIVE;
  541. lpIMC->fdwInit |= INIT_CONVERSION;
  542. }
  543. #if !defined(ROMANIME)
  544. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  545. lpImcP->fdwImeMsg |= MSG_ALREADY_SOFTKBD;
  546. }
  547. if (lpIMC->fdwInit & INIT_SENTENCE) {
  548. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
  549. *(LPWORD)&lpIMC->fdwSentence |= IME_SMODE_PHRASEPREDICT;
  550. } else {
  551. }
  552. #endif
  553. if (!(lpIMC->fdwInit & INIT_LOGFONT)) {
  554. HDC hDC;
  555. HGDIOBJ hSysFont;
  556. hDC = GetDC(NULL);
  557. hSysFont = GetCurrentObject(hDC, OBJ_FONT);
  558. GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A);
  559. ReleaseDC(NULL, hDC);
  560. lpIMC->fdwInit |= INIT_LOGFONT;
  561. }
  562. // if this IME is run under Chicago Simplified Chinese version
  563. lpIMC->lfFont.A.lfCharSet = NATIVE_CHARSET;
  564. InitContext(
  565. #if defined(UNIIME)
  566. lpImeL,
  567. #endif
  568. lpIMC, lpImcP);
  569. }
  570. ImmUnlockIMCC(lpIMC->hPrivate);
  571. return (TRUE);
  572. }
  573. /**********************************************************************/
  574. /* ImeSelect() / UniImeSelect() */
  575. /* Return Value: */
  576. /* TRUE - successful, FALSE - failure */
  577. /**********************************************************************/
  578. #if defined(UNIIME)
  579. BOOL WINAPI UniImeSelect(
  580. LPINSTDATAL lpInstL,
  581. LPIMEL lpImeL,
  582. #else
  583. BOOL WINAPI ImeSelect(
  584. #endif
  585. HIMC hIMC,
  586. BOOL fSelect)
  587. {
  588. LPINPUTCONTEXT lpIMC;
  589. BOOL fRet;
  590. if (!hIMC) {
  591. return (TRUE);
  592. }
  593. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  594. if (!lpIMC) {
  595. return (FALSE);
  596. }
  597. #if !defined(ROMANIME)
  598. // to load/free IME table
  599. if (fSelect) {
  600. if (!lpInstL->cRefCount++) {
  601. LoadTable(lpInstL, lpImeL);
  602. }
  603. } else {
  604. if (!--lpInstL->cRefCount) {
  605. FreeTable(lpInstL);
  606. }
  607. }
  608. #endif
  609. fRet = Select(
  610. #if defined(UNIIME)
  611. lpImeL,
  612. #endif
  613. lpIMC, fSelect);
  614. ImmUnlockIMC(hIMC);
  615. return (fRet);
  616. }
  617. /**********************************************************************/
  618. /* ImeSetActiveContext() / UniImeSetActiveContext() */
  619. /* Return Value: */
  620. /* TRUE - successful, FALSE - failure */
  621. /**********************************************************************/
  622. #if defined(UNIIME)
  623. BOOL WINAPI UniImeSetActiveContext(
  624. LPINSTDATAL lpInstL,
  625. LPIMEL lpImeL,
  626. #else
  627. BOOL WINAPI ImeSetActiveContext(
  628. #endif
  629. HIMC hIMC,
  630. BOOL fOn)
  631. {
  632. if (!fOn) {
  633. } else if (!hIMC) {
  634. } else {
  635. LPINPUTCONTEXT lpIMC;
  636. LPPRIVCONTEXT lpImcP;
  637. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  638. if (!lpIMC) {
  639. goto SetActSyncDic;
  640. }
  641. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  642. if (!lpImcP) {
  643. goto SetActUnlockIMC;
  644. }
  645. InitContext(
  646. #if defined(UNIIME)
  647. lpImeL,
  648. #endif
  649. lpIMC, lpImcP);
  650. ImmUnlockIMCC(lpIMC->hPrivate);
  651. SetActUnlockIMC:
  652. ImmUnlockIMC(hIMC);
  653. SetActSyncDic:
  654. ; // NULL statement for goto
  655. #if !defined(ROMANIME) && !defined(WINIME) && !defined(UNICDIME)
  656. if (lpImeL->szUsrDic[0]) {
  657. if (lpInstL->hUsrDicMem) {
  658. } else if (lpImeL->fdwErrMsg & (ERRMSG_LOAD_USRDIC|
  659. ERRMSG_MEM_USRDIC)) {
  660. } else if (lpInstL->fdwTblLoad != TBL_LOADED) {
  661. } else {
  662. LoadUsrDicFile(lpInstL, lpImeL);
  663. }
  664. } else {
  665. if (lpInstL->hUsrDicMem) {
  666. CloseHandle(lpInstL->hUsrDicMem);
  667. lpInstL->hUsrDicMem = (HANDLE)NULL;
  668. }
  669. }
  670. #endif
  671. }
  672. return (TRUE);
  673. }