Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

327 lines
9.7 KiB

/**************************************************************************\
* Module Name: input.c
*
* Copyright (c) Microsoft Corp. 1996 All Rights Reserved
*
* IME key input management routines for imm32 dll
*
* History:
* 01-Apr-1996 takaok split from hotkey.c
\**************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* ImmProcessKey (Callback from Win32K.SYS)
*
* Call ImeProcessKey and IME hotkey handler
*
* History:
* 01-Mar-1996 TakaoK Created
\***************************************************************************/
DWORD WINAPI ImmProcessKey(
HWND hWnd,
HIMC hIMC,
HKL hkl,
UINT uVKey,
LONG lParam,
DWORD dwHotKeyID)
{
PIMEDPI pImeDpi;
PINPUTCONTEXT pInputContext;
DWORD dwReturn = 0;
//
// call ImeProcessKey
//
pImeDpi = ImmLockImeDpi(hkl);
if ( pImeDpi != NULL ) {
pInputContext = ImmLockIMC( hIMC );
if ( pInputContext != NULL ) {
PBYTE pbKeyState;
pbKeyState = (PBYTE)LocalAlloc( LMEM_FIXED, 256);
if ( pbKeyState != NULL ) {
if ( GetKeyboardState( pbKeyState ) ) {
if ( (*pImeDpi->pfn.ImeProcessKey)(hIMC, uVKey, lParam, pbKeyState) ) {
//
// if the return value of ImeProcessKey is TRUE,
// it means the key is the one that the ime is
// waiting for.
//
pInputContext->fChgMsg = TRUE;
pInputContext->uSavedVKey = uVKey;
dwReturn |= IPHK_PROCESSBYIME;
}
}
LocalFree( pbKeyState );
}
ImmUnlockIMC( hIMC );
}
ImmUnlockImeDpi(pImeDpi);
}
//
// call hotkey handler
//
if ( dwHotKeyID != IME_INVALID_HOTKEY &&
HotKeyIDDispatcher( hWnd, hIMC, hkl, dwHotKeyID) )
{
dwReturn |= IPHK_HOTKEY;
}
return dwReturn;
}
#define TRANSMSGCOUNT 256
/***************************************************************************\
* ImmTranslateMessage (Called from user\client\ntstubs.c\TranslateMessage())
*
* Call ImeToAsciiEx()
*
* History:
* 01-Mar-1996 TakaoK Created
\***************************************************************************/
BOOL ImmTranslateMessage(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
HIMC hImc;
PINPUTCONTEXT pInputContext;
BOOL fReturn = FALSE;
HKL hkl;
PIMEDPI pImeDpi;
PBYTE pbKeyState;
PDWORD pdwTransBuf;
IMEINFOEX iiex;
PIMEINFOEX piiex;
UINT uVKey;
INT iNum;
INT MessageCount = TRANSMSGCOUNT;
//
// we're interested in only those keyboard messages.
//
switch (message) {
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
break;
default:
return FALSE;
}
//
// input context is necessary for further handling
//
hImc = ImmGetContext( hwnd );
pInputContext = ImmLockIMC( hImc );
if ( pInputContext == NULL ) {
ImmReleaseContext( hwnd, hImc );
return FALSE;
}
//
// At first, handle VK_PROCESSKEY generated by IME.
//
if ( ! pInputContext->fChgMsg ) {
if ( (iNum=pInputContext->dwNumMsgBuf) != 0 ) {
PDWORD pdwt;
PDWORD pdwt2;
pdwt = (PDWORD)ImmLockIMCC(pInputContext->hMsgBuf);
if ( pdwt != NULL ) {
INT cbBuf = (iNum * 3 ) * sizeof(DWORD);
//
// LATER : allocating a temporary buffer
// is not needed for 4.x application
//
pdwt2 = LocalAlloc( LMEM_FIXED, cbBuf );
if ( pdwt2 != NULL ) {
RtlCopyMemory( pdwt2, pdwt, cbBuf );
ImmPostMessages( hwnd, hImc, iNum, pdwt2);
LocalFree( pdwt2 );
fReturn = TRUE;
}
ImmUnlockIMCC(pInputContext->hMsgBuf);
}
pInputContext->dwNumMsgBuf = 0;
}
goto ExitITM;
}
pInputContext->fChgMsg = FALSE;
//
// retrieve the keyboard layout and IME entry points
//
hkl = GetKeyboardLayout( GetWindowThreadProcessId(hwnd, NULL) );
pImeDpi = ImmLockImeDpi(hkl);
if ( pImeDpi == NULL ) {
RIPMSG1(RIP_WARNING, "ImmTranslateMessage pImeDpi is NULL(hkl=%x)", hkl);
goto ExitITM;
}
//
// get IME info
//
piiex = &iiex;
if ( ! ImmGetImeInfoEx(piiex, ImeInfoExKeyboardLayout, (PVOID)&hkl) ) {
RIPMSG0(RIP_WARNING, "ImmTranslateMessage ImmGetImeInfoEx failed" );
goto ExitITM;
}
//
// allocate buffers
//
pbKeyState = LocalAlloc( LMEM_FIXED, 256 );
if ( pbKeyState == NULL ) {
RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
goto ExitITM;
}
if ( ! GetKeyboardState( pbKeyState ) ) {
RIPMSG0(RIP_WARNING, "ImmTranslateMessage GetKeyboardState() failed" );
LocalFree( pbKeyState );
goto ExitITM;
}
pdwTransBuf = (PDWORD)LocalAlloc( LMEM_FIXED, (MessageCount*3+1)*sizeof(DWORD));
if ( pdwTransBuf == NULL ) {
RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
LocalFree( pbKeyState );
goto ExitITM;
}
//
// Translate the saved vkey into character code if needed
//
uVKey = pInputContext->uSavedVKey;
if ( piiex->ImeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST ) {
if ( piiex->ImeInfo.fdwProperty & IME_PROP_UNICODE ) {
iNum = ToUnicode( pInputContext->uSavedVKey, // virtual-key code
HIWORD(lParam), // scan code
pbKeyState, // key-state array
(LPWSTR)pdwTransBuf, // buffer for translated key
1, // size of buffer
0);
if ( iNum == 1 ) {
//
// hi word : unicode character code
// hi byte of lo word : zero
// lo byte of lo word : virtual key
//
uVKey = (uVKey & 0x00ff) | ( ((DWORD)(*(PWCHAR)pdwTransBuf)) << 16 );
}
} else {
iNum = ToAsciiEx( pInputContext->uSavedVKey, // virtual-key code
HIWORD(lParam), // scan code
pbKeyState, // key-state array
(LPWORD)pdwTransBuf, // buffer for translated key
0, // active-menu flag
hkl);
if ( iNum > 0 ) {
//
// hi word : should be zero
// hi byte of lo word : character code
// lo byte of lo word : virtual key
//
uVKey = (uVKey & 0x00FF) | ( ((DWORD)(*(PBYTE)pdwTransBuf)) << 8);
uVKey &= 0x0000ffff;
}
}
}
//
// Call IME
//
*pdwTransBuf = MessageCount;
iNum = (*pImeDpi->pfn.ImeToAsciiEx)( uVKey,
HIWORD(lParam),
pbKeyState,
pdwTransBuf,
0,
hImc);
if ( iNum > MessageCount ) {
//
// The message buffer is not big enough. IME put messages
// into hMsgBuf in the input context.
//
PDWORD pdwt;
pdwt = (PDWORD)ImmLockIMCC(pInputContext->hMsgBuf);
if ( pdwt != NULL ) {
LocalFree( pdwTransBuf );
pdwTransBuf = LocalAlloc( LMEM_FIXED, iNum * 3 * sizeof(DWORD) );
if ( pdwTransBuf != NULL ) {
RtlCopyMemory( pdwTransBuf, pdwt, iNum * 3 * sizeof(DWORD) );
ImmPostMessages( hwnd, hImc, iNum, pdwTransBuf );
}
ImmUnlockIMCC(pInputContext->hMsgBuf);
}
}
if ( iNum > 0 ) {
ImmPostMessages( hwnd, hImc, iNum, pdwTransBuf+1 );
fReturn = TRUE;
}
LocalFree( pbKeyState );
LocalFree( pdwTransBuf );
ExitITM:
ImmUnlockIMC( hImc );
ImmReleaseContext( hwnd, hImc );
return fReturn;
}
/***************************************************************************\
* ImmPostMessages(Called from ImmTranslateMessage() )
*
* Post IME messages to application. If application is 3.x, messages
* are translated to old IME messages.
*
* History:
* 01-Mar-1996 TakaoK Created
\***************************************************************************/
VOID
ImmPostMessages(
HWND hWnd,
HIMC hImc,
INT iNum,
PDWORD pdwt)
{
INT i;
BOOL fAnsi;
PCLIENTIMC pClientImc;
pClientImc = ImmLockClientImc(hImc);
if (pClientImc == NULL) {
RIPMSG1(RIP_WARNING,
"ImmPostMessages: Invalid hImc %lx.", hImc);
return;
}
fAnsi = !TestICF(pClientImc, IMCF_UNICODE);
ImmUnlockClientImc(pClientImc);
#ifdef LATER
//
// translate messages to 3.x format if the App's version is 3.x.
//
#endif
for ( i = 0; i < iNum; i++ ) {
if (fAnsi) {
PostMessageA( hWnd, (UINT)*pdwt, (WPARAM)*(pdwt+1), (LPARAM)*(pdwt+2) );
} else {
PostMessageW( hWnd, (UINT)*pdwt, (WPARAM)*(pdwt+1), (LPARAM)*(pdwt+2) );
}
pdwt += 3;
}
}