2020-09-30 16:53:55 +02:00

461 lines
12 KiB
C

// Copyright (c) 1985 - 1999, Microsoft Corporation
//
// MODULE: imefull.c
//
// PURPOSE: Console IME control.
//
// PLATFORMS: Windows NT-J 3.51
//
// FUNCTIONS:
// ImeOpenClose() - calls initialization functions, processes message loop
//
// History:
//
// 27.Jul.1995 v-HirShi (Hirotoshi Shimizu) created
//
// COMMENTS:
//
#include "precomp.h"
#pragma hdrstop
//**********************************************************************
//
// IMEOpenClose()
//
// This routines calls IMM API to open or close IME.
//
//**********************************************************************
VOID ImeOpenClose( HWND hWnd, BOOL fFlag )
{
HIMC hIMC;
//
// If fFlag is true then open IME; otherwise close it.
//
if ( !( hIMC = ImmGetContext( hWnd ) ) )
return;
ImmSetOpenStatus( hIMC, fFlag );
ImmReleaseContext( hWnd, hIMC );
}
#ifdef DEBUG_MODE
/************************************************************************
*
* VirtualKeyHandler - WM_KEYDOWN handler
*
*
* INPUT: HWND - handle to the window for repainting output.
* UINT - virtual key code.
*
************************************************************************/
VOID VirtualKeyHandler( HWND hWnd, UINT wParam, UINT lParam )
{
PCONSOLE_TABLE ConTbl;
int i;
static int delta ;
ConTbl = SearchConsole(LastConsole);
if (ConTbl == NULL) {
DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
return;
}
if ( ConTbl->fInCandidate ||
( ConTbl->fInComposition && !MoveCaret( hWnd ) )
)
return;
switch( wParam )
{
case VK_HOME: // beginning of line
xPos = FIRSTCOL;
break;
case VK_END: // end of line
xPos = xPosLast ;
break;
case VK_RIGHT:
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){
if (xPos > xPosLast - 2 ) break; //last character don't move
xPos += 2; //skip 2 for DB Character
}
else
xPos = min( xPos+1, xPosLast );
break;
case VK_LEFT:
xPos = max( xPos-1, FIRSTCOL );
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) )
xPos--;
break;
case VK_BACK: // backspace
if ( xPos > FIRSTCOL ) {
delta = 1 ;
//
// DB Character so backup one more to allign on boundary
//
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) )
delta = 2 ;
//
// Fall Through to VK_DELETE to adjust row
//
xPos -= delta ;
for ( i = xPos ; i < xPosLast+2 ; i++) {
ConvertLine[i] = ConvertLine[i+delta] ;
ConvertLineAtr[i] = ConvertLineAtr[i+delta] ;
}
xPosLast -= delta ;
}
else //FIRST COLUMN don't backup -- this would change for wrapping
break;
goto Repaint ;
break;
case VK_DELETE:
if ( !IsUnicodeFullWidth( ConvertLine[xPos] ) ) {
//
// Move rest of line left by one, then blank out last character
//
for ( i = xPos; i < xPosLast; i++ ) {
ConvertLine[i] = ConvertLine[i+1];
ConvertLineAtr[i] = ConvertLineAtr[i+1];
}
xPosLast-- ;
} else {
//
// Move line left by two bytes, blank out last two bytes
//
for ( i = xPos; i < xPosLast; i++ ) {
ConvertLine[i] = ConvertLine[i+2];
ConvertLineAtr[i] = ConvertLineAtr[i+2];
}
xPosLast -= 2 ;
}
goto Repaint ;
break;
case VK_TAB: // tab -- tabs are column allignment not character
{
int xTabMax = xPos + TABSTOP;
int xPosPrev;
do {
xPosPrev = xPos;
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){
if (xPos > xPosLast - 2 ) break; //last character don't move
xPos += 2; //skip 2 for DB Character
}
else
xPos = min( xPos+1, xPosLast );
} while ( (xPos % TABSTOP) &&
(xPos < xTabMax) &&
(xPos != xPosPrev));
}
goto Repaint ;
break;
case VK_RETURN: // linefeed
for (i = FIRSTCOL ; i < MAXCOL ; i++) {
ConvertLine[i] = ' ' ;
ConvertLineAtr[i] = 0 ;
}
xPos = FIRSTCOL;
xPosLast = FIRSTCOL;
Repaint:
{
//
// Repaint the entire line
//
HDC hdc;
hdc = GetDC( hWnd );
HideCaret( hWnd );
DisplayConvInformation( hWnd ) ;
ReleaseDC( hWnd, hdc );
}
break;
}
ResetCaret( hWnd );
}
#endif
/************************************************************************
*
* CharHandler - WM_CHAR handler
*
************************************************************************/
VOID CharHandlerFromConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam)
{
UINT TmpMessage ;
DWORD dwImmRet ;
UINT uVKey ;
UINT wParamSave ;
if (HIWORD(wParam) == 0){
wParamSave = wParam ;
}
else {
if (Message == WM_KEYDOWN +CONIME_KEYDATA || Message == WM_KEYUP +CONIME_KEYDATA ||
Message == WM_SYSKEYDOWN+CONIME_KEYDATA || Message == WM_SYSKEYUP+CONIME_KEYDATA){
wParamSave = 0 ;
}
else if(HIWORD(wParam) > 0x00ff){
WCHAR WideChar ;
UCHAR MultiChar ;
WideChar = HIWORD(wParam) ;
WideCharToMultiByte(CP_OEMCP, 0, &WideChar, 1, &MultiChar, 1, NULL, NULL) ;
wParamSave = MultiChar ;
}
else {
wParamSave = HIWORD(wParam) ;
}
}
if (HIWORD(lParam) & KF_UP) // KEY_TRANSITION_UP
TmpMessage = WM_KEYUP ;
else
TmpMessage = WM_KEYDOWN ;
// Return Value of ClientImmProcessKeyConsoleIME
// IPHK_HOTKEY 1 - the vkey is IME hotkey
// IPHK_PROCESSBYIME 2 - the vkey is the one that the IME is waiting for
// IPHK_CHECKCTRL 4 - not used by NT IME
dwImmRet = ImmCallImeConsoleIME(hWnd, TmpMessage, wParam, lParam, &uVKey) ;
if ( dwImmRet & IPHK_HOTKEY ) {
//
// if this vkey is the IME hotkey, we won't pass
// it to application or hook procedure.
// This is what Win95 does. [takaok]
//
return ;
}
else if (dwImmRet & IPHK_PROCESSBYIME) {
BOOL Status ;
//3.51
// uVKey = (wParamSave<<8) | uVKey ;
// Status = ClientImmTranslateMessageMain( hWnd,uVKey,lParam);
Status = ImmTranslateMessage(hWnd, TmpMessage, wParam, lParam);
}
else if (dwImmRet & IPHK_CHECKCTRL) {
CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam);
}
else
{
if ((Message == WM_CHAR +CONIME_KEYDATA)||
(Message == WM_SYSCHAR+CONIME_KEYDATA)) {
CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam);
}
else
CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParam, lParam);
}
}
VOID CharHandlerToConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam)
{
PCONSOLE_TABLE ConTbl;
WORD ch ;
int NumByte = 0 ;
ConTbl = SearchConsole(LastConsole);
if (ConTbl == NULL) {
DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
return;
}
if (HIWORD(lParam) & KF_UP ) {
PostMessage( ConTbl->hWndCon,
Message+CONIME_KEYDATA,
wParam,
lParam) ;
return ;
}
ch = LOWORD(wParam) ;
if ((ch < UNICODE_SPACE) ||
((ch >= UNICODE_SPACE) &&
((Message == WM_KEYDOWN) || (Message == WM_SYSKEYDOWN) ))) {
#ifdef DEBUG_MODE
VirtualKeyHandler( hWnd, wParam ,lParam) ;
#endif
PostMessage( ConTbl->hWndCon,
Message+CONIME_KEYDATA,
wParam,
lParam) ;
return ;
}
#ifdef DEBUG_MODE
StoreChar( hWnd, ch, 0);
#endif
PostMessage( ConTbl->hWndCon,
Message+CONIME_KEYDATA,
wParam, //*Dest,
lParam) ;
}
#ifdef DEBUG_MODE
//**********************************************************************
//
// void ImeUIMove()
//
// Handler routine of WM_MOVE message.
//
//*********************************************************************
VOID ImeUIMoveCandWin( HWND hwnd )
{
PCONSOLE_TABLE ConTbl;
ConTbl = SearchConsole(LastConsole);
if (ConTbl == NULL) {
DBGPRINT(("CONIME: Error! Cannot found registed Console\n"));
return;
}
if ( ConTbl->fInCandidate )
{
POINT point; // Storage for caret position.
int i; // loop counter.
int NumCandWin; // Storage for num of cand win.
RECT rect; // Storage for client rect.
//
// If current IME state is in chosing candidate, here we
// move all candidate windows, if any, to the appropriate
// position based on the parent window's position.
//
NumCandWin = 0;
GetCaretPos( (LPPOINT)&point );
ClientToScreen( hwnd, (LPPOINT)&point );
for ( i = 0; i < MAX_LISTCAND ; i++ )
{
if ( ConTbl->hListCand[ i ] )
{
GetClientRect( ConTbl->hListCand[ i ], &rect );
MoveWindow( ConTbl->hListCand[ i ],
point.x + X_INDENT * NumCandWin,
point.y + Y_INDENT * NumCandWin + cyMetrics,
( rect.right - rect.left + 1 ),
( rect.bottom - rect.top + 1 ), TRUE );
NumCandWin++;
}
}
}
}
#endif
#ifdef DEBUG_MODE
/************************************************************************
*
* ResetCaret - Reset caret shape to match input mode (overtype/insert)
*
************************************************************************/
VOID ResetCaret( HWND hWnd )
{
HideCaret( hWnd );
DestroyCaret();
CreateCaret( hWnd,
NULL,
IsUnicodeFullWidth( ConvertLine[xPos] ) ?
CaretWidth*2 : CaretWidth,
cyMetrics );
SetCaretPos( xPos * cxMetrics, 0 );
ShowCaret( hWnd );
}
//**********************************************************************
//
// BOOL MoveCaret()
//
//**********************************************************************
BOOL MoveCaret( HWND hwnd )
{
HIMC hIMC;
BOOL retVal = TRUE;
if ( !( hIMC = ImmGetContext( hwnd ) ) )
return retVal;
if ( ImmGetCompositionString( hIMC, GCS_CURSORPOS,
(void FAR *)NULL, 0 ) )
retVal = FALSE;
ImmReleaseContext( hwnd, hIMC );
return retVal;
}
#endif
#ifdef DEBUG_MODE
/************************************************************************
*
* StoreChar - Stores one character into text buffer and advances
* cursor
*
************************************************************************/
VOID StoreChar( HWND hWnd, WORD ch, UCHAR atr )
{
HDC hdc;
if ( xPos >= CVMAX-3 )
return;
//
// Store input character at current caret position
//
ConvertLine[xPos] = ch;
ConvertLineAtr[xPos] = atr;
xPos++ ;
xPosLast = max(xPosLast,xPos) ;
//
// Repaint the entire line
//
hdc = GetDC( hWnd );
HideCaret( hWnd );
DisplayConvInformation( hWnd ) ;
ResetCaret( hWnd );
ReleaseDC( hWnd, hdc );
}
#endif