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.

618 lines
20 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. SUBS.C
  5. ++*/
  6. /**********************************************************************/
  7. #include <windows.h>
  8. #include "immdev.h"
  9. #include "fakeime.h"
  10. /**********************************************************************/
  11. /* */
  12. /* InitCompStr() */
  13. /* */
  14. /**********************************************************************/
  15. void PASCAL InitCompStr(LPCOMPOSITIONSTRING lpCompStr,DWORD dwClrFlag)
  16. {
  17. lpCompStr->dwSize = sizeof(MYCOMPSTR);
  18. if (dwClrFlag & CLR_UNDET)
  19. {
  20. lpCompStr->dwCompReadAttrOffset =
  21. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->bCompReadAttr - (LONG_PTR) lpCompStr);
  22. lpCompStr->dwCompReadClauseOffset =
  23. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->dwCompReadClause - (LONG_PTR)lpCompStr);
  24. lpCompStr->dwCompReadStrOffset =
  25. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->szCompReadStr - (LONG_PTR)lpCompStr);
  26. lpCompStr->dwCompAttrOffset =
  27. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->bCompAttr - (LONG_PTR)lpCompStr);
  28. lpCompStr->dwCompClauseOffset =
  29. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->dwCompClause - (LONG_PTR)lpCompStr);
  30. lpCompStr->dwCompStrOffset =
  31. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->szCompStr - (LONG_PTR)lpCompStr);
  32. lpCompStr->dwCompStrLen = 0;
  33. lpCompStr->dwCompReadStrLen = 0;
  34. lpCompStr->dwCompAttrLen = 0;
  35. lpCompStr->dwCompReadAttrLen = 0;
  36. lpCompStr->dwCompClauseLen = 0;
  37. lpCompStr->dwCompReadClauseLen = 0;
  38. *GETLPCOMPSTR(lpCompStr) = MYTEXT('\0');
  39. *GETLPCOMPREADSTR(lpCompStr) = MYTEXT('\0');
  40. lpCompStr->dwCursorPos = 0;
  41. }
  42. if (dwClrFlag & CLR_RESULT)
  43. {
  44. lpCompStr->dwResultStrOffset =
  45. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->szResultStr - (LONG_PTR)lpCompStr);
  46. lpCompStr->dwResultClauseOffset =
  47. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->dwResultClause - (LONG_PTR)lpCompStr);
  48. lpCompStr->dwResultReadStrOffset =
  49. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->szResultReadStr - (LONG_PTR)lpCompStr);
  50. lpCompStr->dwResultReadClauseOffset =
  51. (DWORD) ((LONG_PTR)((LPMYCOMPSTR)lpCompStr)->dwResultReadClause - (LONG_PTR)lpCompStr);
  52. lpCompStr->dwResultStrLen = 0;
  53. lpCompStr->dwResultClauseLen = 0;
  54. lpCompStr->dwResultReadStrLen = 0;
  55. lpCompStr->dwResultReadClauseLen = 0;
  56. *GETLPRESULTSTR(lpCompStr) = MYTEXT('\0');
  57. *GETLPRESULTREADSTR(lpCompStr) = MYTEXT('\0');
  58. }
  59. }
  60. /**********************************************************************/
  61. /* */
  62. /* ClearCompStr() */
  63. /* */
  64. /**********************************************************************/
  65. void PASCAL ClearCompStr(LPCOMPOSITIONSTRING lpCompStr,DWORD dwClrFlag)
  66. {
  67. lpCompStr->dwSize = sizeof(MYCOMPSTR);
  68. if (dwClrFlag & CLR_UNDET)
  69. {
  70. lpCompStr->dwCompStrOffset = 0;
  71. lpCompStr->dwCompClauseOffset = 0;
  72. lpCompStr->dwCompAttrOffset = 0;
  73. lpCompStr->dwCompReadStrOffset = 0;
  74. lpCompStr->dwCompReadClauseOffset = 0;
  75. lpCompStr->dwCompReadAttrOffset = 0;
  76. lpCompStr->dwCompStrLen = 0;
  77. lpCompStr->dwCompClauseLen = 0;
  78. lpCompStr->dwCompAttrLen = 0;
  79. lpCompStr->dwCompReadStrLen = 0;
  80. lpCompStr->dwCompReadClauseLen = 0;
  81. lpCompStr->dwCompReadAttrLen = 0;
  82. ((LPMYCOMPSTR)lpCompStr)->szCompStr[0] = MYTEXT('\0');
  83. ((LPMYCOMPSTR)lpCompStr)->szCompReadStr[0] = MYTEXT('\0');
  84. lpCompStr->dwCursorPos = 0;
  85. }
  86. if (dwClrFlag & CLR_RESULT)
  87. {
  88. lpCompStr->dwResultStrOffset = 0;
  89. lpCompStr->dwResultClauseOffset = 0;
  90. lpCompStr->dwResultReadStrOffset = 0;
  91. lpCompStr->dwResultReadClauseOffset = 0;
  92. lpCompStr->dwResultStrLen = 0;
  93. lpCompStr->dwResultClauseLen = 0;
  94. lpCompStr->dwResultReadStrLen = 0;
  95. lpCompStr->dwResultReadClauseLen = 0;
  96. ((LPMYCOMPSTR)lpCompStr)->szResultStr[0] = MYTEXT('\0');
  97. ((LPMYCOMPSTR)lpCompStr)->szResultReadStr[0] = MYTEXT('\0');
  98. }
  99. }
  100. /**********************************************************************/
  101. /* */
  102. /* ClearCandidate() */
  103. /* */
  104. /**********************************************************************/
  105. void PASCAL ClearCandidate(LPCANDIDATEINFO lpCandInfo)
  106. {
  107. lpCandInfo->dwSize = 0L;
  108. lpCandInfo->dwCount = 0L;
  109. lpCandInfo->dwOffset[0] = 0L;
  110. ((LPMYCAND)lpCandInfo)->cl.dwSize =0L;
  111. ((LPMYCAND)lpCandInfo)->cl.dwStyle =0L;
  112. ((LPMYCAND)lpCandInfo)->cl.dwCount =0L;
  113. ((LPMYCAND)lpCandInfo)->cl.dwSelection =0L;
  114. ((LPMYCAND)lpCandInfo)->cl.dwPageStart =0L;
  115. ((LPMYCAND)lpCandInfo)->cl.dwPageSize =0L;
  116. ((LPMYCAND)lpCandInfo)->cl.dwOffset[0] =0L;
  117. }
  118. /**********************************************************************/
  119. /* */
  120. /* ChangeMode() */
  121. /* */
  122. /* return value: fdwConversion */
  123. /* */
  124. /**********************************************************************/
  125. void PASCAL ChangeMode(HIMC hIMC, DWORD dwToMode)
  126. {
  127. LPINPUTCONTEXT lpIMC;
  128. DWORD fdwConversion;
  129. TRANSMSG GnMsg;
  130. if (!(lpIMC = ImmLockIMC(hIMC)))
  131. return;
  132. fdwConversion = lpIMC->fdwConversion;
  133. switch (dwToMode)
  134. {
  135. case TO_CMODE_ALPHANUMERIC:
  136. fdwConversion = (fdwConversion & ~IME_CMODE_LANGUAGE);
  137. break;
  138. case TO_CMODE_KATAKANA:
  139. fdwConversion |= (IME_CMODE_NATIVE | IME_CMODE_KATAKANA);
  140. break;
  141. case TO_CMODE_HIRAGANA:
  142. fdwConversion =
  143. ((fdwConversion & ~IME_CMODE_LANGUAGE) | IME_CMODE_NATIVE);
  144. fdwConversion |= IME_CMODE_FULLSHAPE;
  145. break;
  146. case TO_CMODE_FULLSHAPE:
  147. if (fdwConversion & IME_CMODE_FULLSHAPE)
  148. {
  149. // To SBCS mode.
  150. fdwConversion &= ~IME_CMODE_FULLSHAPE;
  151. // If hiragana mode, make it katakana mode.
  152. if ((fdwConversion & IME_CMODE_LANGUAGE) == IME_CMODE_NATIVE)
  153. fdwConversion |= (IME_CMODE_NATIVE | IME_CMODE_KATAKANA);
  154. }
  155. else
  156. {
  157. // To DBCS mode.
  158. fdwConversion |= IME_CMODE_FULLSHAPE;
  159. }
  160. break;
  161. case TO_CMODE_ROMAN:
  162. if (fdwConversion & IME_CMODE_ROMAN)
  163. fdwConversion &= ~IME_CMODE_ROMAN;
  164. else
  165. fdwConversion |= IME_CMODE_ROMAN;
  166. break;
  167. case TO_CMODE_CHARCODE:
  168. break;
  169. case TO_CMODE_TOOLBAR:
  170. break;
  171. default:
  172. break;
  173. }
  174. if (lpIMC->fdwConversion != fdwConversion)
  175. {
  176. lpIMC->fdwConversion = fdwConversion;
  177. GnMsg.message = WM_IME_NOTIFY;
  178. GnMsg.wParam = IMN_SETCONVERSIONMODE;
  179. GnMsg.lParam = 0L;
  180. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  181. }
  182. ImmUnlockIMC(hIMC);
  183. return;
  184. }
  185. /**********************************************************************/
  186. /* */
  187. /* ChangeCompStr() */
  188. /* */
  189. /**********************************************************************/
  190. void PASCAL ChangeCompStr(HIMC hIMC, DWORD dwToMode)
  191. {
  192. LPINPUTCONTEXT lpIMC;
  193. LPCOMPOSITIONSTRING lpCompStr;
  194. DWORD fdwConversion;
  195. TRANSMSG GnMsg;
  196. HANDLE hDst;
  197. LPMYSTR lpSrc;
  198. LPMYSTR lpDst;
  199. LPMYSTR lpSrc0;
  200. LPMYSTR lpDst0;
  201. WORD wCode;
  202. BOOL fChange = FALSE;
  203. if (!(lpIMC = ImmLockIMC(hIMC)))
  204. return;
  205. if (!(lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr)))
  206. goto ccs_exit40;
  207. fdwConversion = lpIMC->fdwConversion;
  208. #if defined(FAKEIMEM) || defined(UNICODE)
  209. if (!(hDst = GlobalAlloc(GHND,(lpCompStr->dwCompStrLen+1)*sizeof(WCHAR))))
  210. #else
  211. if (!(hDst = GlobalAlloc(GHND,lpCompStr->dwCompStrLen*2)))
  212. #endif
  213. goto ccs_exit30;
  214. if (!(lpDst = GlobalLock(hDst)))
  215. goto ccs_exit20;
  216. switch (dwToMode)
  217. {
  218. case TO_CMODE_ALPHANUMERIC:
  219. break;
  220. case TO_CMODE_KATAKANA:
  221. lpSrc = ((LPMYCOMPSTR)lpCompStr)->szCompStr;
  222. lpSrc0 = lpSrc;
  223. lpDst0 = lpDst;
  224. while (*lpSrc)
  225. {
  226. #if defined(FAKEIMEM) || defined(UNICODE)
  227. *lpDst++ = HiraToKata(*lpSrc);
  228. lpSrc++;
  229. #else
  230. if (IsDBCSLeadByte(*lpSrc))
  231. wCode = (((WORD)*lpSrc << 8) + (WORD)(unsigned char)*(lpSrc+1));
  232. else
  233. wCode = (WORD)(unsigned char)*lpSrc & 0xFF;
  234. wCode = HiraToKata(wCode);
  235. if (IsDBCSLeadByte((BYTE)(wCode >> 8)))
  236. *lpDst++ = (BYTE)(wCode >> 8);
  237. *lpDst++ = (BYTE)(wCode & 0xFF);
  238. lpSrc = AnsiNext(lpSrc);
  239. #endif
  240. }
  241. Mylstrcpy (lpSrc0,lpDst0);
  242. lpCompStr->dwCompStrLen = Mylstrlen(lpSrc0);
  243. fChange = TRUE;
  244. break;
  245. case TO_CMODE_HIRAGANA:
  246. lpSrc = ((LPMYCOMPSTR)lpCompStr)->szCompStr;
  247. lpSrc0 = lpSrc;
  248. lpDst0 = lpDst;
  249. while (*lpSrc)
  250. {
  251. #if defined(FAKEIMEM) || defined(UNICODE)
  252. *lpDst++ = KataToHira(*lpSrc);
  253. lpSrc++;
  254. #else
  255. if (IsDBCSLeadByte(*lpSrc))
  256. wCode = ((WORD)(*lpSrc << 8) + (WORD)(unsigned char)*(lpSrc+1));
  257. else
  258. wCode = (WORD)(unsigned char)*lpSrc & 0xFF;
  259. wCode = KataToHira(wCode);
  260. if (IsDBCSLeadByte((BYTE)(wCode >> 8)))
  261. *lpDst++ = (BYTE)(wCode >> 8);
  262. *lpDst++ = (BYTE)(wCode & 0xFF);
  263. lpSrc = AnsiNext(lpSrc);
  264. #endif
  265. }
  266. Mylstrcpy (lpSrc0,lpDst0);
  267. lpCompStr->dwCompStrLen = Mylstrlen(lpSrc0);
  268. fChange = TRUE;
  269. break;
  270. case TO_CMODE_FULLSHAPE:
  271. break;
  272. case TO_CMODE_ROMAN:
  273. break;
  274. }
  275. if (fChange)
  276. {
  277. GnMsg.message = WM_IME_COMPOSITION;
  278. GnMsg.wParam = 0;
  279. GnMsg.lParam = GCS_COMPSTR;
  280. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  281. }
  282. GlobalUnlock(hDst);
  283. ccs_exit20:
  284. GlobalFree(hDst);
  285. ccs_exit30:
  286. ImmUnlockIMCC(lpIMC->hCompStr);
  287. ccs_exit40:
  288. ImmUnlockIMC(hIMC);
  289. return;
  290. }
  291. /*****************************************************************************
  292. * *
  293. * IsCompStr( hIMC ) *
  294. * *
  295. *****************************************************************************/
  296. BOOL PASCAL IsCompStr(HIMC hIMC)
  297. {
  298. LPINPUTCONTEXT lpIMC;
  299. LPCOMPOSITIONSTRING lpCompStr;
  300. BOOL fRet = FALSE;
  301. if (!(lpIMC = ImmLockIMC(hIMC)))
  302. return FALSE;
  303. if (ImmGetIMCCSize(lpIMC->hCompStr) < sizeof (COMPOSITIONSTRING))
  304. {
  305. ImmUnlockIMC(hIMC);
  306. return FALSE;
  307. }
  308. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  309. fRet = (lpCompStr->dwCompStrLen > 0);
  310. ImmUnlockIMCC(lpIMC->hCompStr);
  311. ImmUnlockIMC(hIMC);
  312. return fRet;
  313. }
  314. /*****************************************************************************
  315. * *
  316. * IsConvertedCompStr( hIMC ) *
  317. * *
  318. *****************************************************************************/
  319. BOOL PASCAL IsConvertedCompStr(HIMC hIMC)
  320. {
  321. LPINPUTCONTEXT lpIMC;
  322. LPCOMPOSITIONSTRING lpCompStr;
  323. BOOL fRet = FALSE;
  324. if (!(lpIMC = ImmLockIMC(hIMC)))
  325. return FALSE;
  326. if (ImmGetIMCCSize(lpIMC->hCompStr) < sizeof (MYCOMPSTR))
  327. {
  328. ImmUnlockIMC(hIMC);
  329. return FALSE;
  330. }
  331. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  332. if (lpCompStr->dwCompStrLen > 0)
  333. fRet = (((LPMYCOMPSTR)lpCompStr)->bCompAttr[0] > 0);
  334. ImmUnlockIMCC(lpIMC->hCompStr);
  335. ImmUnlockIMC(hIMC);
  336. return fRet;
  337. }
  338. /*****************************************************************************
  339. * *
  340. * IsCandidate( lpIMC ) *
  341. * *
  342. *****************************************************************************/
  343. BOOL PASCAL IsCandidate(LPINPUTCONTEXT lpIMC)
  344. {
  345. LPCANDIDATEINFO lpCandInfo;
  346. BOOL fRet = FALSE;
  347. if (ImmGetIMCCSize(lpIMC->hCandInfo) < sizeof (CANDIDATEINFO))
  348. return FALSE;
  349. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  350. fRet = (lpCandInfo->dwCount > 0);
  351. ImmUnlockIMCC(lpIMC->hCandInfo);
  352. return fRet;
  353. }
  354. /**********************************************************************/
  355. /* */
  356. /* GetMyHKL() */
  357. /* */
  358. /**********************************************************************/
  359. HKL PASCAL GetMyHKL()
  360. {
  361. DWORD dwSize;
  362. DWORD dwi;
  363. HKL hKL = 0;
  364. HKL *lphkl;
  365. dwSize = GetKeyboardLayoutList(0, NULL);
  366. lphkl = (HKL *)GlobalAlloc(GPTR, dwSize * sizeof(DWORD));
  367. if (!lphkl)
  368. return NULL;
  369. GetKeyboardLayoutList(dwSize, lphkl);
  370. for (dwi = 0; dwi < dwSize; dwi++)
  371. {
  372. TCHAR szFile[32];
  373. HKL hKLTemp = *(lphkl + dwi);
  374. ImmGetIMEFileName(hKLTemp, szFile, sizeof(szFile)/sizeof(szFile[0]));
  375. if (!lstrcmp(szFile, MyFileName))
  376. {
  377. hKL = hKLTemp;
  378. goto exit;
  379. }
  380. }
  381. exit:
  382. GlobalFree((HANDLE)lphkl);
  383. return hKL;
  384. }
  385. /*****************************************************************************
  386. * *
  387. * UpdateIndicIcon( hIMC ) *
  388. * *
  389. *****************************************************************************/
  390. void PASCAL UpdateIndicIcon(HIMC hIMC)
  391. {
  392. HWND hwndIndicate;
  393. BOOL fOpen = FALSE;
  394. LPINPUTCONTEXT lpIMC;
  395. if (!hMyKL)
  396. {
  397. hMyKL = GetMyHKL();
  398. if (!hMyKL)
  399. return;
  400. }
  401. hwndIndicate = FindWindow(INDICATOR_CLASS, NULL);
  402. if (hIMC)
  403. {
  404. lpIMC = ImmLockIMC(hIMC);
  405. if (lpIMC)
  406. {
  407. fOpen = lpIMC->fOpen;
  408. ImmUnlockIMC(hIMC);
  409. }
  410. }
  411. if (IsWindow(hwndIndicate))
  412. {
  413. ATOM atomTip;
  414. atomTip = GlobalAddAtom(TEXT("FakeIME Open"));
  415. PostMessage(hwndIndicate, INDICM_SETIMEICON,
  416. fOpen ? 1 : (-1), (LPARAM)hMyKL);
  417. PostMessage(hwndIndicate, INDICM_SETIMETOOLTIPS,
  418. fOpen ? atomTip : (-1), (LPARAM)hMyKL);
  419. PostMessage(hwndIndicate, INDICM_REMOVEDEFAULTMENUITEMS,
  420. // fOpen ? (RDMI_LEFT | RDMI_RIGHT) : 0, (LPARAM)hMyKL);
  421. fOpen ? (RDMI_LEFT) : 0, (LPARAM)hMyKL);
  422. }
  423. }
  424. /*****************************************************************************
  425. * *
  426. * lememset( ) *
  427. * *
  428. *****************************************************************************/
  429. void PASCAL lmemset(LPBYTE lp, BYTE b, UINT cnt)
  430. {
  431. register UINT i;
  432. register BYTE bt = b;
  433. for (i=0;i<cnt;i++)
  434. *lp++ = bt;
  435. }
  436. #if defined(FAKEIMEM) || defined(UNICODE)
  437. /*****************************************************************************
  438. * *
  439. * MylstrcmpW( ) *
  440. * *
  441. *****************************************************************************/
  442. int PASCAL MylstrcmpW(LPWSTR lp0, LPWSTR lp1)
  443. {
  444. while(*lp0 && *lp1 && (*lp0 == *lp1)) {
  445. lp0++;
  446. lp1++;
  447. }
  448. return (*lp0 - *lp1);
  449. }
  450. /*****************************************************************************
  451. * *
  452. * MylstrcpyW( ) *
  453. * *
  454. *****************************************************************************/
  455. int PASCAL MylstrcpyW(LPWSTR lp0, LPWSTR lp1)
  456. {
  457. int n = 0;
  458. while(*lp1)
  459. {
  460. *lp0 = *lp1;
  461. lp0++;
  462. lp1++;
  463. n++;
  464. }
  465. *lp0 = *lp1;
  466. return n;
  467. }
  468. /*****************************************************************************
  469. * *
  470. * MyCharPrevW( ) *
  471. * *
  472. *****************************************************************************/
  473. LPWSTR PASCAL MyCharPrevW(LPWSTR lpStart, LPWSTR lpCur)
  474. {
  475. LPWSTR lpRet = lpStart;
  476. if (lpCur > lpStart)
  477. lpRet = lpCur - 1;
  478. return lpRet;
  479. }
  480. /*****************************************************************************
  481. * *
  482. * MyCharNextW( ) *
  483. * *
  484. *****************************************************************************/
  485. LPWSTR PASCAL MyCharNextW(LPWSTR lp)
  486. {
  487. return lp++;
  488. }
  489. /*****************************************************************************
  490. * *
  491. * MylstrcpynW( ) *
  492. * *
  493. *****************************************************************************/
  494. LPWSTR PASCAL MylstrcpynW(LPWSTR lp0, LPWSTR lp1, int nCount)
  495. {
  496. int n;
  497. for (n = 0; *lp1 && n < nCount - 1; *lp0++ = *lp1++, n++)
  498. ;
  499. *lp0 = L'\0';
  500. return lp0;
  501. }
  502. #endif
  503. HFONT CheckNativeCharset(HDC hDC)
  504. {
  505. BOOL bDiffCharSet = FALSE;
  506. LOGFONT lfFont;
  507. HFONT hOldFont;
  508. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  509. GetObject(hOldFont, sizeof(LOGFONT), &lfFont);
  510. if (lfFont.lfCharSet != NATIVE_CHARSET) {
  511. bDiffCharSet = TRUE;
  512. lfFont.lfWeight = FW_NORMAL;
  513. lfFont.lfCharSet = NATIVE_CHARSET;
  514. lfFont.lfFaceName[0] = TEXT('\0');
  515. SelectObject(hDC, CreateFontIndirect(&lfFont));
  516. } else {
  517. hOldFont = NULL;
  518. }
  519. return hOldFont;
  520. }