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.

460 lines
12 KiB

  1. // Copyright (c) 1985 - 1999, Microsoft Corporation
  2. //
  3. // MODULE: imefull.c
  4. //
  5. // PURPOSE: Console IME control.
  6. //
  7. // PLATFORMS: Windows NT-J 3.51
  8. //
  9. // FUNCTIONS:
  10. // ImeOpenClose() - calls initialization functions, processes message loop
  11. //
  12. // History:
  13. //
  14. // 27.Jul.1995 v-HirShi (Hirotoshi Shimizu) created
  15. //
  16. // COMMENTS:
  17. //
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. //**********************************************************************
  21. //
  22. // IMEOpenClose()
  23. //
  24. // This routines calls IMM API to open or close IME.
  25. //
  26. //**********************************************************************
  27. VOID ImeOpenClose( HWND hWnd, BOOL fFlag )
  28. {
  29. HIMC hIMC;
  30. //
  31. // If fFlag is true then open IME; otherwise close it.
  32. //
  33. if ( !( hIMC = ImmGetContext( hWnd ) ) )
  34. return;
  35. ImmSetOpenStatus( hIMC, fFlag );
  36. ImmReleaseContext( hWnd, hIMC );
  37. }
  38. #ifdef DEBUG_MODE
  39. /************************************************************************
  40. *
  41. * VirtualKeyHandler - WM_KEYDOWN handler
  42. *
  43. *
  44. * INPUT: HWND - handle to the window for repainting output.
  45. * UINT - virtual key code.
  46. *
  47. ************************************************************************/
  48. VOID VirtualKeyHandler( HWND hWnd, UINT wParam, UINT lParam )
  49. {
  50. PCONSOLE_TABLE ConTbl;
  51. int i;
  52. static int delta ;
  53. ConTbl = SearchConsole(LastConsole);
  54. if (ConTbl == NULL) {
  55. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  56. return;
  57. }
  58. if ( ConTbl->fInCandidate ||
  59. ( ConTbl->fInComposition && !MoveCaret( hWnd ) )
  60. )
  61. return;
  62. switch( wParam )
  63. {
  64. case VK_HOME: // beginning of line
  65. xPos = FIRSTCOL;
  66. break;
  67. case VK_END: // end of line
  68. xPos = xPosLast ;
  69. break;
  70. case VK_RIGHT:
  71. if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){
  72. if (xPos > xPosLast - 2 ) break; //last character don't move
  73. xPos += 2; //skip 2 for DB Character
  74. }
  75. else
  76. xPos = min( xPos+1, xPosLast );
  77. break;
  78. case VK_LEFT:
  79. xPos = max( xPos-1, FIRSTCOL );
  80. if ( IsUnicodeFullWidth( ConvertLine[xPos] ) )
  81. xPos--;
  82. break;
  83. case VK_BACK: // backspace
  84. if ( xPos > FIRSTCOL ) {
  85. delta = 1 ;
  86. //
  87. // DB Character so backup one more to allign on boundary
  88. //
  89. if ( IsUnicodeFullWidth( ConvertLine[xPos] ) )
  90. delta = 2 ;
  91. //
  92. // Fall Through to VK_DELETE to adjust row
  93. //
  94. xPos -= delta ;
  95. for ( i = xPos ; i < xPosLast+2 ; i++) {
  96. ConvertLine[i] = ConvertLine[i+delta] ;
  97. ConvertLineAtr[i] = ConvertLineAtr[i+delta] ;
  98. }
  99. xPosLast -= delta ;
  100. }
  101. else //FIRST COLUMN don't backup -- this would change for wrapping
  102. break;
  103. goto Repaint ;
  104. break;
  105. case VK_DELETE:
  106. if ( !IsUnicodeFullWidth( ConvertLine[xPos] ) ) {
  107. //
  108. // Move rest of line left by one, then blank out last character
  109. //
  110. for ( i = xPos; i < xPosLast; i++ ) {
  111. ConvertLine[i] = ConvertLine[i+1];
  112. ConvertLineAtr[i] = ConvertLineAtr[i+1];
  113. }
  114. xPosLast-- ;
  115. } else {
  116. //
  117. // Move line left by two bytes, blank out last two bytes
  118. //
  119. for ( i = xPos; i < xPosLast; i++ ) {
  120. ConvertLine[i] = ConvertLine[i+2];
  121. ConvertLineAtr[i] = ConvertLineAtr[i+2];
  122. }
  123. xPosLast -= 2 ;
  124. }
  125. goto Repaint ;
  126. break;
  127. case VK_TAB: // tab -- tabs are column allignment not character
  128. {
  129. int xTabMax = xPos + TABSTOP;
  130. int xPosPrev;
  131. do {
  132. xPosPrev = xPos;
  133. if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){
  134. if (xPos > xPosLast - 2 ) break; //last character don't move
  135. xPos += 2; //skip 2 for DB Character
  136. }
  137. else
  138. xPos = min( xPos+1, xPosLast );
  139. } while ( (xPos % TABSTOP) &&
  140. (xPos < xTabMax) &&
  141. (xPos != xPosPrev));
  142. }
  143. goto Repaint ;
  144. break;
  145. case VK_RETURN: // linefeed
  146. for (i = FIRSTCOL ; i < MAXCOL ; i++) {
  147. ConvertLine[i] = ' ' ;
  148. ConvertLineAtr[i] = 0 ;
  149. }
  150. xPos = FIRSTCOL;
  151. xPosLast = FIRSTCOL;
  152. Repaint:
  153. {
  154. //
  155. // Repaint the entire line
  156. //
  157. HDC hdc;
  158. hdc = GetDC( hWnd );
  159. HideCaret( hWnd );
  160. DisplayConvInformation( hWnd ) ;
  161. ReleaseDC( hWnd, hdc );
  162. }
  163. break;
  164. }
  165. ResetCaret( hWnd );
  166. }
  167. #endif
  168. /************************************************************************
  169. *
  170. * CharHandler - WM_CHAR handler
  171. *
  172. ************************************************************************/
  173. VOID CharHandlerFromConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam)
  174. {
  175. UINT TmpMessage ;
  176. DWORD dwImmRet ;
  177. UINT uVKey ;
  178. UINT wParamSave ;
  179. if (HIWORD(wParam) == 0){
  180. wParamSave = wParam ;
  181. }
  182. else {
  183. if (Message == WM_KEYDOWN +CONIME_KEYDATA || Message == WM_KEYUP +CONIME_KEYDATA ||
  184. Message == WM_SYSKEYDOWN+CONIME_KEYDATA || Message == WM_SYSKEYUP+CONIME_KEYDATA){
  185. wParamSave = 0 ;
  186. }
  187. else if(HIWORD(wParam) > 0x00ff){
  188. WCHAR WideChar ;
  189. UCHAR MultiChar ;
  190. WideChar = HIWORD(wParam) ;
  191. WideCharToMultiByte(CP_OEMCP, 0, &WideChar, 1, &MultiChar, 1, NULL, NULL) ;
  192. wParamSave = MultiChar ;
  193. }
  194. else {
  195. wParamSave = HIWORD(wParam) ;
  196. }
  197. }
  198. if (HIWORD(lParam) & KF_UP) // KEY_TRANSITION_UP
  199. TmpMessage = WM_KEYUP ;
  200. else
  201. TmpMessage = WM_KEYDOWN ;
  202. // Return Value of ClientImmProcessKeyConsoleIME
  203. // IPHK_HOTKEY 1 - the vkey is IME hotkey
  204. // IPHK_PROCESSBYIME 2 - the vkey is the one that the IME is waiting for
  205. // IPHK_CHECKCTRL 4 - not used by NT IME
  206. dwImmRet = ImmCallImeConsoleIME(hWnd, TmpMessage, wParam, lParam, &uVKey) ;
  207. if ( dwImmRet & IPHK_HOTKEY ) {
  208. //
  209. // if this vkey is the IME hotkey, we won't pass
  210. // it to application or hook procedure.
  211. // This is what Win95 does. [takaok]
  212. //
  213. return ;
  214. }
  215. else if (dwImmRet & IPHK_PROCESSBYIME) {
  216. BOOL Status ;
  217. //3.51
  218. // uVKey = (wParamSave<<8) | uVKey ;
  219. // Status = ClientImmTranslateMessageMain( hWnd,uVKey,lParam);
  220. Status = ImmTranslateMessage(hWnd, TmpMessage, wParam, lParam);
  221. }
  222. else if (dwImmRet & IPHK_CHECKCTRL) {
  223. CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam);
  224. }
  225. else
  226. {
  227. if ((Message == WM_CHAR +CONIME_KEYDATA)||
  228. (Message == WM_SYSCHAR+CONIME_KEYDATA)) {
  229. CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam);
  230. }
  231. else
  232. CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParam, lParam);
  233. }
  234. }
  235. VOID CharHandlerToConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam)
  236. {
  237. PCONSOLE_TABLE ConTbl;
  238. WORD ch ;
  239. int NumByte = 0 ;
  240. ConTbl = SearchConsole(LastConsole);
  241. if (ConTbl == NULL) {
  242. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  243. return;
  244. }
  245. if (HIWORD(lParam) & KF_UP ) {
  246. PostMessage( ConTbl->hWndCon,
  247. Message+CONIME_KEYDATA,
  248. wParam,
  249. lParam) ;
  250. return ;
  251. }
  252. ch = LOWORD(wParam) ;
  253. if ((ch < UNICODE_SPACE) ||
  254. ((ch >= UNICODE_SPACE) &&
  255. ((Message == WM_KEYDOWN) || (Message == WM_SYSKEYDOWN) ))) {
  256. #ifdef DEBUG_MODE
  257. VirtualKeyHandler( hWnd, wParam ,lParam) ;
  258. #endif
  259. PostMessage( ConTbl->hWndCon,
  260. Message+CONIME_KEYDATA,
  261. wParam,
  262. lParam) ;
  263. return ;
  264. }
  265. #ifdef DEBUG_MODE
  266. StoreChar( hWnd, ch, 0);
  267. #endif
  268. PostMessage( ConTbl->hWndCon,
  269. Message+CONIME_KEYDATA,
  270. wParam, //*Dest,
  271. lParam) ;
  272. }
  273. #ifdef DEBUG_MODE
  274. //**********************************************************************
  275. //
  276. // void ImeUIMove()
  277. //
  278. // Handler routine of WM_MOVE message.
  279. //
  280. //*********************************************************************
  281. VOID ImeUIMoveCandWin( HWND hwnd )
  282. {
  283. PCONSOLE_TABLE ConTbl;
  284. ConTbl = SearchConsole(LastConsole);
  285. if (ConTbl == NULL) {
  286. DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
  287. return;
  288. }
  289. if ( ConTbl->fInCandidate )
  290. {
  291. POINT point; // Storage for caret position.
  292. int i; // loop counter.
  293. int NumCandWin; // Storage for num of cand win.
  294. RECT rect; // Storage for client rect.
  295. //
  296. // If current IME state is in chosing candidate, here we
  297. // move all candidate windows, if any, to the appropriate
  298. // position based on the parent window's position.
  299. //
  300. NumCandWin = 0;
  301. GetCaretPos( (LPPOINT)&point );
  302. ClientToScreen( hwnd, (LPPOINT)&point );
  303. for ( i = 0; i < MAX_LISTCAND ; i++ )
  304. {
  305. if ( ConTbl->hListCand[ i ] )
  306. {
  307. GetClientRect( ConTbl->hListCand[ i ], &rect );
  308. MoveWindow( ConTbl->hListCand[ i ],
  309. point.x + X_INDENT * NumCandWin,
  310. point.y + Y_INDENT * NumCandWin + cyMetrics,
  311. ( rect.right - rect.left + 1 ),
  312. ( rect.bottom - rect.top + 1 ), TRUE );
  313. NumCandWin++;
  314. }
  315. }
  316. }
  317. }
  318. #endif
  319. #ifdef DEBUG_MODE
  320. /************************************************************************
  321. *
  322. * ResetCaret - Reset caret shape to match input mode (overtype/insert)
  323. *
  324. ************************************************************************/
  325. VOID ResetCaret( HWND hWnd )
  326. {
  327. HideCaret( hWnd );
  328. DestroyCaret();
  329. CreateCaret( hWnd,
  330. NULL,
  331. IsUnicodeFullWidth( ConvertLine[xPos] ) ?
  332. CaretWidth*2 : CaretWidth,
  333. cyMetrics );
  334. SetCaretPos( xPos * cxMetrics, 0 );
  335. ShowCaret( hWnd );
  336. }
  337. //**********************************************************************
  338. //
  339. // BOOL MoveCaret()
  340. //
  341. //**********************************************************************
  342. BOOL MoveCaret( HWND hwnd )
  343. {
  344. HIMC hIMC;
  345. BOOL retVal = TRUE;
  346. if ( !( hIMC = ImmGetContext( hwnd ) ) )
  347. return retVal;
  348. if ( ImmGetCompositionString( hIMC, GCS_CURSORPOS,
  349. (void FAR *)NULL, 0 ) )
  350. retVal = FALSE;
  351. ImmReleaseContext( hwnd, hIMC );
  352. return retVal;
  353. }
  354. #endif
  355. #ifdef DEBUG_MODE
  356. /************************************************************************
  357. *
  358. * StoreChar - Stores one character into text buffer and advances
  359. * cursor
  360. *
  361. ************************************************************************/
  362. VOID StoreChar( HWND hWnd, WORD ch, UCHAR atr )
  363. {
  364. HDC hdc;
  365. if ( xPos >= CVMAX-3 )
  366. return;
  367. //
  368. // Store input character at current caret position
  369. //
  370. ConvertLine[xPos] = ch;
  371. ConvertLineAtr[xPos] = atr;
  372. xPos++ ;
  373. xPosLast = max(xPosLast,xPos) ;
  374. //
  375. // Repaint the entire line
  376. //
  377. hdc = GetDC( hWnd );
  378. HideCaret( hWnd );
  379. DisplayConvInformation( hWnd ) ;
  380. ResetCaret( hWnd );
  381. ReleaseDC( hWnd, hdc );
  382. }
  383. #endif