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.

970 lines
28 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. NOTIFY.C
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #if defined(UNIIME)
  11. #include "uniime.h"
  12. #endif
  13. /**********************************************************************/
  14. /* GenerateMessage() */
  15. /**********************************************************************/
  16. void PASCAL GenerateMessage(
  17. HIMC hIMC,
  18. LPINPUTCONTEXT lpIMC,
  19. LPPRIVCONTEXT lpImcP)
  20. {
  21. if (!hIMC) {
  22. return;
  23. } else if (!lpIMC) {
  24. return;
  25. } else if (!lpImcP) {
  26. return;
  27. } else if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
  28. return;
  29. } else {
  30. }
  31. lpIMC->dwNumMsgBuf += TranslateImeMessage(NULL, lpIMC, lpImcP);
  32. #if !defined(ROMANIME)
  33. lpImcP->fdwImeMsg &= (MSG_STATIC_STATE);
  34. lpImcP->fdwGcsFlag = 0;
  35. #endif
  36. ImmGenerateMessage(hIMC);
  37. return;
  38. }
  39. #if !defined(ROMANIME)
  40. /**********************************************************************/
  41. /* SetString() */
  42. /* Return Value: */
  43. /* TRUE - successful, FALSE - failure */
  44. /**********************************************************************/
  45. BOOL PASCAL SetString(
  46. #if defined(UNIIME)
  47. LPIMEL lpImeL,
  48. #endif
  49. HIMC hIMC,
  50. LPINPUTCONTEXT lpIMC,
  51. LPCOMPOSITIONSTRING lpCompStr,
  52. LPPRIVCONTEXT lpImcP,
  53. LPTSTR lpszRead,
  54. DWORD dwReadLen)
  55. {
  56. DWORD dwPattern;
  57. LPGUIDELINE lpGuideLine;
  58. DWORD i;
  59. // convert from byte count to the string length
  60. dwReadLen = dwReadLen / sizeof(TCHAR);
  61. if (dwReadLen > lpImeL->nMaxKey * sizeof(WCHAR) / sizeof(TCHAR)) {
  62. return (FALSE);
  63. }
  64. dwPattern = ReadingToPattern(
  65. #if defined(UNIIME)
  66. lpImeL,
  67. #endif
  68. lpszRead, lpImcP->bSeq, FALSE);
  69. if (!dwPattern) {
  70. return (FALSE);
  71. }
  72. InitCompStr(lpCompStr);
  73. ClearCand(lpIMC);
  74. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  75. if (lpGuideLine) {
  76. InitGuideLine(lpGuideLine);
  77. ImmUnlockIMCC(lpIMC->hGuideLine);
  78. }
  79. // compoition/reading attribute
  80. lpCompStr->dwCompReadAttrLen = dwReadLen;
  81. lpCompStr->dwCompAttrLen = lpCompStr->dwCompReadAttrLen;
  82. // The IME has converted these chars
  83. for (i = 0; i < dwReadLen; i++) {
  84. *((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset + i) =
  85. ATTR_TARGET_CONVERTED;
  86. }
  87. // composition/reading clause, 1 clause only
  88. lpCompStr->dwCompReadClauseLen = 2 * sizeof(DWORD);
  89. lpCompStr->dwCompClauseLen = lpCompStr->dwCompReadClauseLen;
  90. *(LPDWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadClauseOffset +
  91. sizeof(DWORD)) = dwReadLen;
  92. lpCompStr->dwCompReadStrLen = dwReadLen;
  93. lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
  94. CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset, lpszRead,
  95. dwReadLen * sizeof(TCHAR) + sizeof(TCHAR));
  96. // dlta start from 0;
  97. lpCompStr->dwDeltaStart = 0;
  98. // cursor is next to composition string
  99. lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
  100. lpCompStr->dwResultReadClauseLen = 0;
  101. lpCompStr->dwResultReadStrLen = 0;
  102. lpCompStr->dwResultClauseLen = 0;
  103. lpCompStr->dwResultStrLen = 0;
  104. // set private input context
  105. lpImcP->iImeState = CST_INPUT;
  106. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  107. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  108. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  109. }
  110. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  111. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) &
  112. ~(MSG_END_COMPOSITION);
  113. }
  114. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  115. lpImcP->dwCompChar = (DWORD)lpImeL->wSeq2CompTbl[
  116. lpImcP->bSeq[lpCompStr->dwCompReadStrLen / 2 - 1]];
  117. #ifndef UNICODE
  118. lpImcP->dwCompChar = HIBYTE(lpImcP->dwCompChar) |
  119. (LOBYTE(lpImcP->dwCompChar) << 8);
  120. #endif
  121. lpImcP->fdwGcsFlag = GCS_COMPREAD|GCS_COMP|
  122. GCS_DELTASTART|GCS_CURSORPOS;
  123. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  124. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  125. #if defined(PHON) || defined(WINIME) || defined(UNICDIME)
  126. if (lpCompStr->dwCompReadStrLen >= sizeof(WORD) * lpImeL->nMaxKey) {
  127. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  128. lpImcP->fdwGcsFlag |= GCS_RESULTREAD|GCS_RESULTSTR;
  129. }
  130. #endif
  131. } else {
  132. #if defined(PHON) || defined(WINIME) || defined(UNICDIME)
  133. if (dwReadLen < sizeof(WCHAR) / sizeof(TCHAR) * lpImeL->nMaxKey) {
  134. #elif defined(QUICK)
  135. if (dwReadLen < sizeof(WCHAR) / sizeof(TCHAR) * 2) {
  136. #else
  137. {
  138. #endif
  139. #if defined(WINAR30)
  140. // quick key
  141. if (lpImeL->fdwModeConfig & MODE_CONFIG_QUICK_KEY) {
  142. Finalize(hIMC, lpIMC, lpCompStr, lpImcP, FALSE);
  143. }
  144. #endif
  145. }
  146. }
  147. GenerateMessage(hIMC, lpIMC, lpImcP);
  148. return (TRUE);
  149. }
  150. /**********************************************************************/
  151. /* CompCancel() */
  152. /**********************************************************************/
  153. void PASCAL CompCancel(
  154. HIMC hIMC,
  155. LPINPUTCONTEXT lpIMC)
  156. {
  157. LPPRIVCONTEXT lpImcP;
  158. if (!lpIMC->hPrivate) {
  159. return;
  160. }
  161. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  162. if (!lpImcP) {
  163. return;
  164. }
  165. lpImcP->fdwGcsFlag = (DWORD) 0;
  166. if (lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|MSG_OPEN_CANDIDATE)) {
  167. CandEscapeKey(lpIMC, lpImcP);
  168. } else if (lpImcP->fdwImeMsg & (MSG_ALREADY_START|MSG_START_COMPOSITION)) {
  169. LPCOMPOSITIONSTRING lpCompStr;
  170. LPGUIDELINE lpGuideLine;
  171. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  172. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  173. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  174. if (lpGuideLine) {
  175. ImmUnlockIMCC(lpIMC->hGuideLine);
  176. }
  177. if (lpCompStr) {
  178. ImmUnlockIMCC(lpIMC->hCompStr);
  179. }
  180. } else {
  181. ImmUnlockIMCC(lpIMC->hPrivate);
  182. return;
  183. }
  184. GenerateMessage(hIMC, lpIMC, lpImcP);
  185. ImmUnlockIMCC(lpIMC->hPrivate);
  186. return;
  187. }
  188. #endif
  189. /**********************************************************************/
  190. /* ImeSetCompositionString() */
  191. /* Return Value: */
  192. /* TRUE - successful, FALSE - failure */
  193. /**********************************************************************/
  194. #if defined(UNIIME)
  195. BOOL WINAPI UniImeSetCompositionString(
  196. LPINSTDATAL lpInstL,
  197. LPIMEL lpImeL,
  198. #else
  199. BOOL WINAPI ImeSetCompositionString(
  200. #endif
  201. HIMC hIMC,
  202. DWORD dwIndex,
  203. LPVOID lpComp,
  204. DWORD dwCompLen,
  205. LPVOID lpRead,
  206. DWORD dwReadLen)
  207. {
  208. #if defined(ROMANIME)
  209. return (FALSE);
  210. #else
  211. LPINPUTCONTEXT lpIMC;
  212. LPCOMPOSITIONSTRING lpCompStr;
  213. LPPRIVCONTEXT lpImcP;
  214. BOOL fRet;
  215. TCHAR szReading[16];
  216. if (!hIMC) {
  217. return (FALSE);
  218. }
  219. // composition string must == reading string
  220. // reading is more important
  221. if (!dwReadLen) {
  222. dwReadLen = dwCompLen;
  223. }
  224. // composition string must == reading string
  225. // reading is more important
  226. if (!lpRead) {
  227. lpRead = lpComp;
  228. }
  229. if (!dwReadLen) {
  230. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  231. if (!lpIMC) {
  232. return (FALSE);
  233. }
  234. CompCancel(hIMC, lpIMC);
  235. ImmUnlockIMC(hIMC);
  236. return (TRUE);
  237. } else if (!lpRead) {
  238. return (FALSE);
  239. } else if (dwReadLen >= sizeof(szReading)) {
  240. return (FALSE);
  241. } else if (!dwCompLen) {
  242. } else if (!lpComp) {
  243. } else if (dwReadLen != dwCompLen) {
  244. return (FALSE);
  245. } else if (lpRead == lpComp) {
  246. } else if (!lstrcmp(lpRead, lpComp)) {
  247. // composition string must == reading string
  248. } else {
  249. // composition string != reading string
  250. return (FALSE);
  251. }
  252. if (dwIndex != SCS_SETSTR) {
  253. return (FALSE);
  254. }
  255. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  256. if (!lpIMC) {
  257. return (FALSE);
  258. }
  259. fRet = FALSE;
  260. if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_SYMBOL)) !=
  261. IME_CMODE_NATIVE) {
  262. goto ImeSetCompStrUnlockIMC;
  263. }
  264. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  265. if (!lpCompStr) {
  266. goto ImeSetCompStrUnlockIMC;
  267. }
  268. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  269. if (!lpImcP) {
  270. goto ImeSetCompStrUnlockCompStr;
  271. }
  272. if (*(LPTSTR)((LPBYTE)lpRead + dwReadLen) != '\0') {
  273. CopyMemory(szReading, (LPBYTE)lpRead, dwReadLen);
  274. lpRead = szReading;
  275. *(LPTSTR)((LPBYTE)lpRead + dwReadLen) = '\0';
  276. }
  277. fRet = SetString(
  278. #if defined(UNIIME)
  279. lpImeL,
  280. #endif
  281. hIMC, lpIMC, lpCompStr, lpImcP, lpRead, dwReadLen);
  282. ImmUnlockIMCC(lpIMC->hPrivate);
  283. ImeSetCompStrUnlockCompStr:
  284. ImmUnlockIMCC(lpIMC->hCompStr);
  285. ImeSetCompStrUnlockIMC:
  286. ImmUnlockIMC(hIMC);
  287. return (fRet);
  288. #endif
  289. }
  290. #if !defined(ROMANIME)
  291. /**********************************************************************/
  292. /* GenerateImeMessage() */
  293. /**********************************************************************/
  294. void PASCAL GenerateImeMessage(
  295. HIMC hIMC,
  296. LPINPUTCONTEXT lpIMC,
  297. DWORD fdwImeMsg)
  298. {
  299. LPPRIVCONTEXT lpImcP;
  300. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  301. if (!lpImcP) {
  302. return;
  303. }
  304. lpImcP->fdwImeMsg |= fdwImeMsg;
  305. if (fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  306. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  307. } else if (fdwImeMsg & (MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE)) {
  308. lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE);
  309. } else {
  310. }
  311. if (fdwImeMsg & MSG_END_COMPOSITION) {
  312. lpImcP->fdwImeMsg &= ~(MSG_START_COMPOSITION);
  313. } else if (fdwImeMsg & MSG_START_COMPOSITION) {
  314. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION);
  315. } else {
  316. }
  317. GenerateMessage(hIMC, lpIMC, lpImcP);
  318. ImmUnlockIMCC(lpIMC->hPrivate);
  319. return;
  320. }
  321. /**********************************************************************/
  322. /* NotifySelectCand() */
  323. /**********************************************************************/
  324. void PASCAL NotifySelectCand( // app tell IME that one candidate string is
  325. // selected (by mouse or non keyboard action
  326. // - for example sound)
  327. #if defined(UNIIME)
  328. LPIMEL lpImeL,
  329. #endif
  330. HIMC hIMC,
  331. LPINPUTCONTEXT lpIMC,
  332. LPCANDIDATEINFO lpCandInfo,
  333. DWORD dwIndex,
  334. DWORD dwValue)
  335. {
  336. LPCANDIDATELIST lpCandList;
  337. LPCOMPOSITIONSTRING lpCompStr;
  338. LPPRIVCONTEXT lpImcP;
  339. if (!lpCandInfo) {
  340. return;
  341. }
  342. if (dwIndex >= lpCandInfo->dwCount) {
  343. // wanted candidate list is not created yet!
  344. return;
  345. } else if (dwIndex == 0) {
  346. } else {
  347. }
  348. lpCandList = (LPCANDIDATELIST)
  349. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  350. // the selected value even more than the number of total candidate
  351. // strings, it is imposible. should be error of app
  352. if (dwValue >= lpCandList->dwCount) {
  353. return;
  354. }
  355. #if defined(WINAR30)
  356. if (!*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwValue])) {
  357. MessageBeep((UINT)-1);
  358. return;
  359. }
  360. #endif
  361. // app select this candidate string
  362. lpCandList->dwSelection = dwValue;
  363. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  364. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  365. // translate into message buffer
  366. SelectOneCand(
  367. #if defined(UNIIME)
  368. lpImeL,
  369. #endif
  370. hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  371. // let app generate those messages in its message loop
  372. GenerateMessage(hIMC, lpIMC, lpImcP);
  373. ImmUnlockIMCC(lpIMC->hPrivate);
  374. ImmUnlockIMCC(lpIMC->hCompStr);
  375. return;
  376. }
  377. #endif
  378. /**********************************************************************/
  379. /* SetConvMode() */
  380. /**********************************************************************/
  381. void PASCAL SetConvMode(
  382. HIMC hIMC,
  383. LPINPUTCONTEXT lpIMC,
  384. DWORD dwIndex)
  385. {
  386. DWORD fdwImeMsg;
  387. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_CHARCODE) {
  388. // reject CHARCODE
  389. lpIMC->fdwConversion &= ~IME_CMODE_CHARCODE;
  390. MessageBeep((UINT)-1);
  391. return;
  392. }
  393. fdwImeMsg = 0;
  394. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_NOCONVERSION) {
  395. lpIMC->fdwConversion |= IME_CMODE_NATIVE;
  396. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  397. IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  398. }
  399. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_EUDC) {
  400. lpIMC->fdwConversion |= IME_CMODE_NATIVE;
  401. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  402. IME_CMODE_NOCONVERSION|IME_CMODE_SYMBOL);
  403. }
  404. #if !defined(ROMANIME) && !defined(WINAR30)
  405. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SOFTKBD) {
  406. LPPRIVCONTEXT lpImcP;
  407. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  408. MessageBeep((UINT)-1);
  409. return;
  410. }
  411. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  412. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  413. } else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  414. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  415. } else {
  416. }
  417. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  418. if (!lpImcP) {
  419. goto NotifySKOvr;
  420. }
  421. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  422. // now we already in soft keyboard state by
  423. // this change
  424. // even end user finish the symbol, we should not
  425. // turn off soft keyboard
  426. lpImcP->fdwImeMsg |= MSG_ALREADY_SOFTKBD;
  427. } else {
  428. // now we are not in soft keyboard state by
  429. // this change
  430. // after end user finish the symbol, we should
  431. // turn off soft keyboard
  432. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_SOFTKBD);
  433. }
  434. ImmUnlockIMCC(lpIMC->hPrivate);
  435. NotifySKOvr:
  436. ; // NULL statement for goto
  437. }
  438. #endif
  439. if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_NATIVE) {
  440. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  441. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  442. #if !defined(ROMANIME) && !defined(WINAR30)
  443. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  444. #endif
  445. }
  446. #if !defined(ROMANIME)
  447. if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SYMBOL) {
  448. LPCOMPOSITIONSTRING lpCompStr;
  449. #if !defined(WINAR30)
  450. LPPRIVCONTEXT lpImcP;
  451. #endif
  452. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  453. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  454. MessageBeep((UINT)-1);
  455. return;
  456. }
  457. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  458. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  459. lpIMC->fdwConversion |= (dwIndex & IME_CMODE_SYMBOL);
  460. MessageBeep((UINT)-1);
  461. return;
  462. }
  463. lpCompStr = ImmLockIMCC(lpIMC->hCompStr);
  464. if (lpCompStr) {
  465. if (!lpCompStr->dwCompStrLen) {
  466. } else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  467. // if there is a string we could not change
  468. // to symbol mode
  469. lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
  470. MessageBeep((UINT)-1);
  471. return;
  472. } else {
  473. }
  474. ImmUnlockIMCC(lpIMC->hCompStr);
  475. }
  476. lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
  477. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC);
  478. #if !defined(WINAR30)
  479. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  480. lpIMC->fdwConversion |= IME_CMODE_SOFTKBD;
  481. } else if (lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate)) {
  482. // we borrow the bit for this usage
  483. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_SOFTKBD)) {
  484. lpIMC->fdwConversion &= ~(IME_CMODE_SOFTKBD);
  485. }
  486. ImmUnlockIMCC(lpIMC->hPrivate);
  487. } else {
  488. }
  489. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  490. #endif
  491. }
  492. #endif
  493. #if !defined(ROMANIME) && !defined(WINAR30)
  494. if (fdwImeMsg) {
  495. GenerateImeMessage(hIMC, lpIMC, fdwImeMsg);
  496. }
  497. #endif
  498. if ((lpIMC->fdwConversion ^ dwIndex) & ~(IME_CMODE_FULLSHAPE|
  499. IME_CMODE_SOFTKBD)) {
  500. } else {
  501. return;
  502. }
  503. #if !defined(ROMANIME)
  504. CompCancel(hIMC, lpIMC);
  505. #endif
  506. return;
  507. }
  508. #if !defined(ROMANIME)
  509. /**********************************************************************/
  510. /* CompComplete() */
  511. /**********************************************************************/
  512. void PASCAL CompComplete(
  513. #if defined(UNIIME)
  514. LPINSTDATAL lpInstL,
  515. LPIMEL lpImeL,
  516. #endif
  517. HIMC hIMC,
  518. LPINPUTCONTEXT lpIMC)
  519. {
  520. LPPRIVCONTEXT lpImcP;
  521. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  522. if (!lpImcP) {
  523. return;
  524. }
  525. if (lpImcP->iImeState == CST_INIT) {
  526. // can not do any thing
  527. CompCancel(hIMC, lpIMC);
  528. } else if (lpImcP->iImeState == CST_CHOOSE) {
  529. LPCOMPOSITIONSTRING lpCompStr;
  530. LPCANDIDATEINFO lpCandInfo;
  531. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  532. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  533. if (lpCandInfo) {
  534. LPCANDIDATELIST lpCandList;
  535. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  536. lpCandInfo->dwOffset[0]);
  537. SelectOneCand(
  538. #if defined(UNIIME)
  539. lpImeL,
  540. #endif
  541. hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  542. ImmUnlockIMCC(lpIMC->hCandInfo);
  543. GenerateMessage(hIMC, lpIMC, lpImcP);
  544. }
  545. if (lpCompStr) ImmUnlockIMCC(lpIMC->hCompStr);
  546. } else if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|
  547. IME_CMODE_EUDC|IME_CMODE_SYMBOL)) != IME_CMODE_NATIVE) {
  548. CompCancel(hIMC, lpIMC);
  549. } else if (lpImcP->iImeState == CST_INPUT) {
  550. LPCOMPOSITIONSTRING lpCompStr;
  551. LPGUIDELINE lpGuideLine;
  552. LPCANDIDATEINFO lpCandInfo;
  553. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  554. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  555. CompWord(
  556. #if defined(UNIIME)
  557. lpInstL, lpImeL,
  558. #endif
  559. ' ', hIMC, lpIMC, lpCompStr, lpGuideLine, lpImcP);
  560. if (lpImcP->iImeState == CST_INPUT) {
  561. CompCancel(hIMC, lpIMC);
  562. } else if (lpImcP->iImeState != CST_CHOOSE) {
  563. } else if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(
  564. lpIMC->hCandInfo)) {
  565. LPCANDIDATELIST lpCandList;
  566. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  567. lpCandInfo->dwOffset[0]);
  568. SelectOneCand(
  569. #if defined(UNIIME)
  570. lpImeL,
  571. #endif
  572. hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  573. ImmUnlockIMCC(lpIMC->hCandInfo);
  574. } else {
  575. }
  576. if (lpCompStr) ImmUnlockIMCC(lpIMC->hCompStr);
  577. if (lpGuideLine) ImmUnlockIMCC(lpIMC->hGuideLine);
  578. // don't phrase predition under this case
  579. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  580. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  581. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  582. } else {
  583. lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE|MSG_OPEN_CANDIDATE);
  584. }
  585. GenerateMessage(hIMC, lpIMC, lpImcP);
  586. } else {
  587. CompCancel(hIMC, lpIMC);
  588. }
  589. ImmUnlockIMCC(lpIMC->hPrivate);
  590. return;
  591. }
  592. #endif
  593. /**********************************************************************/
  594. /* NotifyIME() / UniNotifyIME() */
  595. /* Return Value: */
  596. /* TRUE - successful, FALSE - failure */
  597. /**********************************************************************/
  598. #if defined(UNIIME)
  599. BOOL WINAPI UniNotifyIME(
  600. LPINSTDATAL lpInstL,
  601. LPIMEL lpImeL,
  602. #else
  603. BOOL WINAPI NotifyIME(
  604. #endif
  605. HIMC hIMC,
  606. DWORD dwAction,
  607. DWORD dwIndex,
  608. DWORD dwValue)
  609. {
  610. LPINPUTCONTEXT lpIMC;
  611. BOOL fRet;
  612. fRet = FALSE;
  613. if (!hIMC) {
  614. return (fRet);
  615. }
  616. switch (dwAction) {
  617. case NI_OPENCANDIDATE: // after a composition string is determined
  618. // if an IME can open candidate, it will.
  619. // if it can not, app also can not open it.
  620. case NI_CLOSECANDIDATE:
  621. return (fRet); // not supported
  622. case NI_SELECTCANDIDATESTR:
  623. case NI_SETCANDIDATE_PAGESTART:
  624. case NI_SETCANDIDATE_PAGESIZE:
  625. #if defined(ROMANIME)
  626. return (fRet);
  627. #else
  628. break; // need to handle it
  629. #endif
  630. case NI_CHANGECANDIDATELIST:
  631. return (TRUE); // not important to the IME
  632. case NI_CONTEXTUPDATED:
  633. switch (dwValue) {
  634. case IMC_SETCONVERSIONMODE:
  635. case IMC_SETSENTENCEMODE:
  636. case IMC_SETOPENSTATUS:
  637. break; // need to handle it
  638. case IMC_SETCANDIDATEPOS:
  639. case IMC_SETCOMPOSITIONFONT:
  640. case IMC_SETCOMPOSITIONWINDOW:
  641. return (TRUE); // not important to the IME
  642. default:
  643. return (fRet); // not supported
  644. }
  645. break;
  646. case NI_COMPOSITIONSTR:
  647. switch (dwIndex) {
  648. #if !defined(ROMANIME)
  649. case CPS_COMPLETE:
  650. break; // need to handle it
  651. case CPS_CONVERT: // all composition string can not be convert
  652. case CPS_REVERT: // any more, it maybe work for some
  653. // intelligent phonetic IMEs
  654. return (fRet);
  655. case CPS_CANCEL:
  656. break; // need to handle it
  657. #endif
  658. default:
  659. return (fRet); // not supported
  660. }
  661. break; // need to handle it
  662. default:
  663. return (fRet); // not supported
  664. }
  665. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  666. if (!lpIMC) {
  667. return (fRet);
  668. }
  669. fRet = TRUE;
  670. switch (dwAction) {
  671. case NI_CONTEXTUPDATED:
  672. switch (dwValue) {
  673. case IMC_SETCONVERSIONMODE:
  674. SetConvMode(hIMC, lpIMC, dwIndex);
  675. break;
  676. case IMC_SETSENTENCEMODE:
  677. #if !defined(ROMANIME)
  678. //if ((WORD)lpIMC->fdwSentence == IME_SMODE_PHRASEPREDICT) {
  679. if (lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT) {
  680. if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|
  681. IME_CMODE_EUDC)) != IME_CMODE_NATIVE) {
  682. lpIMC->fdwSentence = dwIndex;
  683. break;
  684. }
  685. } else {
  686. LPPRIVCONTEXT lpImcP;
  687. lpImcP = ImmLockIMCC(lpIMC->hPrivate);
  688. if (lpImcP) {
  689. if (lpImcP->iImeState == CST_INIT) {
  690. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  691. ClearCand(lpIMC);
  692. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg|
  693. MSG_CLOSE_CANDIDATE) & ~(MSG_OPEN_CANDIDATE|
  694. MSG_CHANGE_CANDIDATE);
  695. GenerateMessage(hIMC, lpIMC, lpImcP);
  696. } else if (lpImcP->fdwImeMsg & (MSG_OPEN_CANDIDATE|
  697. MSG_CHANGE_CANDIDATE)) {
  698. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|
  699. MSG_CHANGE_CANDIDATE);
  700. } else {
  701. }
  702. }
  703. ImmUnlockIMCC(lpIMC->hPrivate);
  704. }
  705. }
  706. #endif
  707. break;
  708. case IMC_SETOPENSTATUS:
  709. #if !defined(ROMANIME)
  710. #if !defined(WINAR30)
  711. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  712. GenerateImeMessage(hIMC, lpIMC, MSG_IMN_UPDATE_SOFTKBD);
  713. }
  714. #endif
  715. CompCancel(hIMC, lpIMC);
  716. #endif
  717. break;
  718. default:
  719. break;
  720. }
  721. break;
  722. #if !defined(ROMANIME)
  723. case NI_SELECTCANDIDATESTR:
  724. if (!lpIMC->fOpen) {
  725. fRet = FALSE;
  726. break;
  727. } else if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
  728. fRet = FALSE;
  729. break;
  730. #if defined(WINAR30) || defined(DAYI)
  731. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  732. fRet = FALSE;
  733. break;
  734. #else
  735. } else if (lpIMC->fdwConversion & (IME_CMODE_EUDC|IME_CMODE_SYMBOL)) {
  736. fRet = FALSE;
  737. break;
  738. #endif
  739. } else if (!lpIMC->hCandInfo) {
  740. fRet = FALSE;
  741. break;
  742. } else {
  743. LPCANDIDATEINFO lpCandInfo;
  744. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  745. NotifySelectCand(
  746. #if defined(UNIIME)
  747. lpImeL,
  748. #endif
  749. hIMC, lpIMC, lpCandInfo, dwIndex, dwValue);
  750. ImmUnlockIMCC(lpIMC->hCandInfo);
  751. }
  752. break;
  753. case NI_SETCANDIDATE_PAGESTART:
  754. case NI_SETCANDIDATE_PAGESIZE:
  755. if (dwIndex != 0) {
  756. fRet = FALSE;
  757. break;
  758. } else if (!lpIMC->fOpen) {
  759. fRet = FALSE;
  760. break;
  761. } else if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
  762. fRet = FALSE;
  763. break;
  764. } else if (lpIMC->fdwConversion & (IME_CMODE_EUDC|IME_CMODE_SYMBOL)) {
  765. fRet = FALSE;
  766. break;
  767. } else if (!lpIMC->hCandInfo) {
  768. fRet = FALSE;
  769. break;
  770. } else {
  771. LPCANDIDATEINFO lpCandInfo;
  772. LPCANDIDATELIST lpCandList;
  773. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  774. if (!lpCandInfo) {
  775. fRet = FALSE;
  776. break;
  777. }
  778. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  779. lpCandInfo->dwOffset[0]);
  780. if (dwAction == NI_SETCANDIDATE_PAGESTART) {
  781. if (dwValue < lpCandList->dwCount) {
  782. lpCandList->dwPageStart = lpCandList->dwSelection =
  783. dwValue;
  784. }
  785. } else {
  786. if (dwValue) {
  787. lpCandList->dwPageSize = dwValue;
  788. }
  789. }
  790. GenerateImeMessage(hIMC, lpIMC, MSG_CHANGE_CANDIDATE);
  791. ImmUnlockIMCC(lpIMC->hCandInfo);
  792. }
  793. break;
  794. case NI_COMPOSITIONSTR:
  795. switch (dwIndex) {
  796. case CPS_CANCEL:
  797. CompCancel(hIMC, lpIMC);
  798. break;
  799. case CPS_COMPLETE:
  800. CompComplete(
  801. #if defined(UNIIME)
  802. lpInstL, lpImeL,
  803. #endif
  804. hIMC, lpIMC);
  805. break;
  806. default:
  807. break;
  808. }
  809. break;
  810. #endif // !defined(ROMANIME)
  811. default:
  812. break;
  813. }
  814. ImmUnlockIMC(hIMC);
  815. return (fRet);
  816. }