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.

394 lines
12 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. chcand.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include <imedefs.h>
  9. #if defined(CROSSREF)
  10. //*******************************************************************
  11. // The parameters are inherited from SelectOneCand
  12. // CrossReverseConv()
  13. //*******************************************************************
  14. void CrossReverseConv(
  15. LPINPUTCONTEXT lpIMC,
  16. LPCOMPOSITIONSTRING lpCompStr,
  17. LPPRIVCONTEXT lpImcP,
  18. LPCANDIDATELIST lpCandList)
  19. {
  20. LPGUIDELINE lpGuideLine;
  21. if (!sImeG.hRevKL) {
  22. return;
  23. }
  24. lpGuideLine = ImmLockIMCC(lpIMC->hGuideLine);
  25. if (!lpGuideLine) {
  26. return;
  27. }
  28. if (lpCompStr->dwResultStrLen != sizeof(WORD)/sizeof(TCHAR)) {
  29. // we only can reverse convert one DBCS character for now
  30. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  31. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  32. } else {
  33. TCHAR szStrBuf[4];
  34. UINT uSize;
  35. LPCANDIDATELIST lpRevCandList;
  36. if(lpImcP->hRevCandList == (HIMCC)NULL){
  37. // we alloc memory in lpImcP->hRevCandList,
  38. // for reverse convert result codes; When finish reconvert,
  39. // should read out this info.
  40. REALLOC:
  41. lpImcP->hRevCandList = (HIMCC)GlobalAlloc(GHND,sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR));
  42. if (lpImcP->hRevCandList == (HIMCC)NULL) {
  43. return ;
  44. }
  45. lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
  46. if (lpRevCandList == NULL) {
  47. return ;
  48. }
  49. }else{
  50. lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
  51. if (lpRevCandList == NULL) {
  52. goto REALLOC;
  53. }
  54. }
  55. *(LPUNAWORD)szStrBuf = *(LPUNAWORD)((LPBYTE)lpCompStr +
  56. lpCompStr->dwResultStrOffset);
  57. szStrBuf[1] = TEXT('\0');
  58. memset(lpRevCandList, 0, sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR));
  59. lpRevCandList->dwSize = sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR);
  60. uSize = ImmGetConversionList(sImeG.hRevKL, (HIMC)NULL, szStrBuf,
  61. (LPCANDIDATELIST)lpRevCandList,
  62. lpRevCandList->dwSize, GCL_REVERSECONVERSION);
  63. GlobalUnlock((HGLOBAL)lpImcP->hRevCandList);
  64. if (uSize) {
  65. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  66. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION|
  67. MSG_START_COMPOSITION);
  68. } else {
  69. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg|
  70. MSG_START_COMPOSITION) & ~(MSG_END_COMPOSITION);
  71. }
  72. } else {
  73. GlobalFree((HGLOBAL)lpImcP->hRevCandList);
  74. }
  75. }
  76. ImmUnlockIMCC(lpIMC->hGuideLine);
  77. }
  78. #endif //CROSSREF
  79. /**********************************************************************/
  80. /* SelectOneCand() */
  81. /**********************************************************************/
  82. void PASCAL SelectOneCand(
  83. LPINPUTCONTEXT lpIMC,
  84. LPCOMPOSITIONSTRING lpCompStr,
  85. LPPRIVCONTEXT lpImcP,
  86. LPCANDIDATELIST lpCandList)
  87. {
  88. DWORD dwCompStrLen;
  89. DWORD dwReadStrLen;
  90. if (!lpCompStr) {
  91. MessageBeep((UINT)-1);
  92. return;
  93. }
  94. if (!lpImcP) {
  95. MessageBeep((UINT)-1);
  96. return;
  97. }
  98. // backup the dwCompStrLen, this value decide whether
  99. // we go for phrase prediction
  100. dwCompStrLen = lpCompStr->dwCompStrLen;
  101. dwReadStrLen = lpCompStr->dwCompReadStrLen;
  102. InitCompStr(lpCompStr);
  103. // calculate result string length
  104. lpCompStr->dwResultStrLen = lstrlen(
  105. (LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
  106. lpCandList->dwSelection]));
  107. // the result string = the selected candidate;
  108. lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),
  109. (LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
  110. lpCandList->dwSelection]));
  111. // tell application, there is a reslut string
  112. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  113. lpImcP->dwCompChar = (DWORD)0;
  114. lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  115. GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
  116. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  117. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  118. ~(MSG_OPEN_CANDIDATE);
  119. }
  120. // no candidate now, the right candidate string already be finalized
  121. lpCandList->dwCount = 0;
  122. lpImcP->iImeState = CST_INIT;
  123. // init Engine private data
  124. *(LPDWORD)lpImcP->bSeq = 0;
  125. #ifdef CROSSREF
  126. CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList);
  127. #endif
  128. return;
  129. }
  130. /**********************************************************************/
  131. /* CandEscapeKey() */
  132. /**********************************************************************/
  133. void PASCAL CandEscapeKey(
  134. LPINPUTCONTEXT lpIMC,
  135. LPPRIVCONTEXT lpImcP)
  136. {
  137. LPCOMPOSITIONSTRING lpCompStr;
  138. LPGUIDELINE lpGuideLine;
  139. // clean all candidate information
  140. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  141. ClearCand(lpIMC);
  142. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  143. ~(MSG_OPEN_CANDIDATE);
  144. }
  145. // if it start composition, we need to clean composition
  146. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  147. return;
  148. }
  149. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  150. if (!lpCompStr) {
  151. return;
  152. }
  153. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  154. if (!lpGuideLine) {
  155. return;
  156. }
  157. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  158. ImmUnlockIMCC(lpIMC->hGuideLine);
  159. ImmUnlockIMCC(lpIMC->hCompStr);
  160. return;
  161. }
  162. /**********************************************************************/
  163. /* ChooseCand() */
  164. /**********************************************************************/
  165. void PASCAL ChooseCand( // choose one of candidate strings by
  166. // input char
  167. WORD wCharCode,
  168. LPINPUTCONTEXT lpIMC,
  169. LPCANDIDATEINFO lpCandInfo,
  170. LPPRIVCONTEXT lpImcP)
  171. {
  172. LPCANDIDATELIST lpCandList;
  173. LPCOMPOSITIONSTRING lpCompStr;
  174. if (wCharCode == VK_ESCAPE) { // escape key
  175. CandEscapeKey(lpIMC, lpImcP);
  176. return;
  177. }
  178. if (!lpCandInfo) {
  179. MessageBeep((UINT)-1);
  180. return;
  181. }
  182. lpCandList = (LPCANDIDATELIST)
  183. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  184. if (wCharCode == TEXT(' ')) { // circle selection
  185. if ((lpCandList->dwSelection += lpCandList->dwPageSize) >=
  186. lpCandList->dwCount) {
  187. // no more candidates, restart it!
  188. lpCandList->dwSelection = 0;
  189. MessageBeep((UINT)-1);
  190. }
  191. // inform UI, dwSelectedCand is changed
  192. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  193. return;
  194. }
  195. if (wCharCode == TEXT('=')) { // next selection
  196. #if defined(COMBO_IME)
  197. if(sImeL.dwRegImeIndex == INDEX_GB){
  198. if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  199. MessageBeep((UINT)-1);
  200. return;
  201. }
  202. }else if(sImeL.dwRegImeIndex == INDEX_GBK){
  203. if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  204. MessageBeep((UINT)-1);
  205. return;
  206. }
  207. }else if(sImeL.dwRegImeIndex == INDEX_UNICODE){
  208. if (lpCandList->dwSelection >= ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  209. MessageBeep((UINT)-1);
  210. return;
  211. }
  212. }
  213. #else //COMBO_IME
  214. #if defined(GB)
  215. if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  216. #else
  217. if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  218. #endif
  219. MessageBeep((UINT)-1);
  220. return;
  221. }
  222. #endif //COMBO_IME
  223. lpCandList->dwSelection += lpCandList->dwPageSize;
  224. // inform UI, dwSelectedCand is changed
  225. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  226. return;
  227. }
  228. if (wCharCode == TEXT('-')) { // previous selection
  229. if (lpCandList->dwSelection < lpCandList->dwPageSize) {
  230. MessageBeep((UINT)-1);
  231. return;
  232. }
  233. lpCandList->dwSelection -= lpCandList->dwPageSize;
  234. // inform UI, dwSelectedCand is changed
  235. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  236. return;
  237. }
  238. if (wCharCode == 0x23) { // previous selection
  239. #if defined(COMBO_IME)
  240. if(sImeL.dwRegImeIndex == INDEX_GB){
  241. if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  242. MessageBeep((UINT)-1);
  243. return;
  244. }else{
  245. lpCandList->dwSelection = ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
  246. }
  247. }else if(sImeL.dwRegImeIndex == INDEX_GBK){
  248. if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  249. MessageBeep((UINT)-1);
  250. return;
  251. }else{
  252. lpCandList->dwSelection = ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
  253. }
  254. }else if(sImeL.dwRegImeIndex == INDEX_UNICODE){
  255. if (lpCandList->dwSelection >= ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  256. MessageBeep((UINT)-1);
  257. return;
  258. }else{
  259. lpCandList->dwSelection = ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
  260. }
  261. }
  262. #else //COMBO_IME
  263. #if defined(GB)
  264. if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
  265. #else
  266. if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE - 1)*lpCandList->dwPageSize) {
  267. #endif
  268. MessageBeep((UINT)-1);
  269. return;
  270. }
  271. #if defined(GB)
  272. lpCandList->dwSelection = ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
  273. #else
  274. lpCandList->dwSelection = ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
  275. #endif
  276. #endif //COMBO_IME
  277. // inform UI, dwSelectedCand is changed
  278. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  279. return;
  280. }
  281. if (wCharCode == 0x24) {
  282. if (lpCandList->dwSelection < lpCandList->dwPageSize) {
  283. MessageBeep((UINT)-1);
  284. return;
  285. }
  286. lpCandList->dwSelection = 0;
  287. // inform UI, dwSelectedCand is changed
  288. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  289. return;
  290. }
  291. if (wCharCode == TEXT('?')) { // home selection
  292. if (lpCandList->dwSelection == 0) {
  293. MessageBeep((UINT)-1); // already home!
  294. return;
  295. }
  296. lpCandList->dwSelection = 0;
  297. // inform UI, dwSelectedCand is changed
  298. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  299. return;
  300. }
  301. if ((wCharCode >= TEXT('0')) && wCharCode <= TEXT('9')) {
  302. DWORD dwSelCand;
  303. dwSelCand = wCharCode - TEXT('0') - CAND_START;
  304. if(wCharCode == TEXT('0')) {
  305. dwSelCand = 9;
  306. }
  307. if (dwSelCand >= CANDPERPAGE) {
  308. // out of candidate page range
  309. MessageBeep((UINT)-1);
  310. return;
  311. }
  312. if ((lpCandList->dwSelection + dwSelCand) >=
  313. lpCandList->dwCount) {
  314. // out of range
  315. MessageBeep((UINT)-1);
  316. return;
  317. }
  318. lpCandList->dwSelection = lpCandList->dwSelection + dwSelCand;
  319. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  320. if (!lpCompStr) {
  321. return;
  322. }
  323. // translate into translate buffer
  324. SelectOneCand(lpIMC, lpCompStr, lpImcP, lpCandList);
  325. ImmUnlockIMCC(lpIMC->hCompStr);
  326. return;
  327. }
  328. return;
  329. }