Implemented keyboard layout and context - far from complete.

oldstable
Hidenori Takeshima 2000-12-18 03:51:16 +00:00 committed by Alexandre Julliard
parent a2d11df25b
commit a257b96dd3
8 changed files with 1181 additions and 186 deletions

View File

@ -9,6 +9,8 @@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
imc.c \
imekl.c \
imewnd.c \
imm.c \
main.c \

254
dlls/imm32/imc.c 100644
View File

@ -0,0 +1,254 @@
/*
* Input Method Context
*
* Copyright 2000 Hidenori Takeshima
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
static HIMC IMM32_CreateIMC( HKL hkl );
static BOOL IMM32_DestroyIMC( HIMC hIMC );
IMM32_IMC* IMM32_LockIMC( HIMC hIMC )
{
IMM32_IMC* pIMC;
if ( hIMC == NULLIMC )
{
SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
if ( !pIMC->fSelected )
{
(void)IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
SetLastError( ERROR_ACCESS_DENIED );
return NULL;
}
return pIMC;
}
BOOL IMM32_UnlockIMC( HIMC hIMC )
{
if ( hIMC == NULLIMC )
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
}
static HIMC IMM32_CreateIMC( HKL hkl )
{
IMM32_MOVEABLEMEM* hIMC;
IMM32_IMC* pIMC;
LPCOMPOSITIONSTRING lpCompStr;
LPCANDIDATEINFO lpCandInfo;
LPGUIDELINE lpGuideLine;
hIMC = IMM32_MoveableAlloc( 0, sizeof( IMM32_IMC ) );
if ( hIMC == NULL )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULLIMC;
}
pIMC = (IMM32_IMC*)IMM32_MoveableLock( hIMC );
/* Initialize some members of IMC. */
pIMC->context.hWnd = (HWND)NULL;
pIMC->context.fOpen = FALSE;
pIMC->context.hCompStr = (HIMCC)NULL;
pIMC->context.hCandInfo = (HIMCC)NULL;
pIMC->context.hGuideLine = (HIMCC)NULL;
pIMC->context.hPrivate = (HIMCC)NULL;
pIMC->context.dwNumMsgBuf = 0;
pIMC->context.hMsgBuf = (HIMCC)NULL;
pIMC->context.fdwInit = 0;
pIMC->pkl = NULL;
pIMC->fSelected = FALSE;
/* hCompStr, hCandInfo, hGuideLine, hMsgBuf must be allocated. */
pIMC->context.hCompStr = ImmCreateIMCC( sizeof(COMPOSITIONSTRING) );
if ( pIMC->context.hCompStr == (HIMCC)NULL )
goto out_of_memory;
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC( pIMC->context.hCompStr );
if ( lpCompStr == NULL )
goto out_of_memory;
lpCompStr->dwSize = sizeof(COMPOSITIONSTRING);
(void)ImmUnlockIMCC( pIMC->context.hCompStr );
pIMC->context.hCandInfo = ImmCreateIMCC( sizeof(CANDIDATEINFO) );
if ( pIMC->context.hCandInfo == (HIMCC)NULL )
goto out_of_memory;
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC( pIMC->context.hCandInfo );
if ( lpCandInfo == NULL )
goto out_of_memory;
lpCandInfo->dwSize = sizeof(CANDIDATEINFO);
(void)ImmUnlockIMCC( pIMC->context.hCandInfo );
pIMC->context.hGuideLine = ImmCreateIMCC( sizeof(GUIDELINE) );
if ( pIMC->context.hGuideLine == (HIMCC)NULL )
goto out_of_memory;
lpGuideLine = (LPGUIDELINE)ImmLockIMCC( pIMC->context.hGuideLine );
if ( lpGuideLine == NULL )
goto out_of_memory;
lpGuideLine->dwSize = sizeof(GUIDELINE);
(void)ImmUnlockIMCC( pIMC->context.hGuideLine );
pIMC->context.hMsgBuf = ImmCreateIMCC( 0 );
if ( pIMC->context.hMsgBuf == (HIMCC)NULL )
goto out_of_memory;
pIMC->pkl = IMM32_GetIME( hkl );
if ( pIMC->pkl != NULL )
{
/* The current HKL is IME.
* Initialize IME's private context.
*/
if ( pIMC->pkl->imeinfo.dwPrivateDataSize > 0 )
{
pIMC->context.hPrivate = ImmCreateIMCC(
pIMC->pkl->imeinfo.dwPrivateDataSize );
if ( pIMC->context.hPrivate == (HIMCC)NULL )
goto out_of_memory;
}
pIMC->fSelected = TRUE;
if ( !pIMC->pkl->handlers.pImeSelect( (HIMC)hIMC, TRUE ) )
{
pIMC->fSelected = FALSE;
goto out_of_memory;
}
}
(void)IMM32_MoveableUnlock( hIMC );
return (HIMC)hIMC;
out_of_memory:
(void)IMM32_DestroyIMC( (HIMC)hIMC );
SetLastError( ERROR_OUTOFMEMORY );
return NULLIMC;
}
static BOOL IMM32_DestroyIMC( HIMC hIMC )
{
IMM32_IMC* pIMC;
if ( hIMC == NULLIMC )
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
if ( pIMC->context.hWnd != (HWND)NULL )
{
FIXME( "please release lock of the context.hWnd!" );
}
if ( pIMC->fSelected )
{
(void)pIMC->pkl->handlers.pImeSelect( hIMC, FALSE );
pIMC->fSelected = FALSE;
}
if ( pIMC->context.hCompStr != (HIMCC)NULL )
(void)ImmDestroyIMCC(pIMC->context.hCompStr);
if ( pIMC->context.hCandInfo != (HIMCC)NULL )
(void)ImmDestroyIMCC(pIMC->context.hCandInfo);
if ( pIMC->context.hGuideLine != (HIMCC)NULL )
(void)ImmDestroyIMCC(pIMC->context.hGuideLine);
if ( pIMC->context.hPrivate != (HIMCC)NULL )
(void)ImmDestroyIMCC(pIMC->context.hPrivate);
if ( pIMC->context.hMsgBuf != (HIMCC)NULL )
(void)ImmDestroyIMCC(pIMC->context.hMsgBuf);
IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMC );
return TRUE;
}
/***********************************************************************
* ImmCreateContext (IMM32.@)
*/
HIMC WINAPI ImmCreateContext( void )
{
TRACE("()\n");
return IMM32_CreateIMC( GetKeyboardLayout(0) );
}
/***********************************************************************
* ImmDestroyContext (IMM32.@)
*/
BOOL WINAPI ImmDestroyContext( HIMC hIMC )
{
TRACE("(0x%08x)\n",hIMC);
return IMM32_DestroyIMC( hIMC );
}
/***********************************************************************
* ImmLockIMC (IMM32.@)
*/
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
IMM32_IMC* pIMC;
TRACE("(0x%08x)\n", (unsigned)hIMC);
pIMC = IMM32_LockIMC( hIMC );
if ( pIMC == NULL )
return NULL;
return &(pIMC->context);
}
/***********************************************************************
* ImmUnlockIMC (IMM32.@)
*/
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
TRACE("(0x%08x)\n", (unsigned)hIMC);
return IMM32_UnlockIMC( hIMC );
}
/***********************************************************************
* ImmGetIMCLockCount (IMM32.@)
*/
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
TRACE("(0x%08x)\n", (unsigned)hIMC);
if ( hIMC == NULLIMC )
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMC );
}

677
dlls/imm32/imekl.c 100644
View File

@ -0,0 +1,677 @@
/*
* IME Keyboard Layout
*
* Copyright 2000 Hidenori Takeshima
*/
#include "config.h"
#include <string.h>
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winreg.h"
#include "immddk.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
static const char IMM32_szRegKL[] =
"System\\CurrentControlSet\\Control\\keyboard layouts";
static const char IMM32_szIME_File[] = "IME file";
static const char IMM32_szLayout_File[] = "layout file";
static IMM32_IMEKL* IMM32_pklFirst = NULL;
static LONG IMM32_RegOpenKey( HKL hkl, PHKEY phkRet )
{
CHAR szRegPath[ sizeof(IMM32_szRegKL)+16 ];
wsprintfA( szRegPath, "%s\\%08x", IMM32_szRegKL, (unsigned)hkl );
return RegOpenKeyExA( HKEY_LOCAL_MACHINE, szRegPath,
0, KEY_READ, phkRet );
}
static LONG IMM32_RegCreateKey( HKL hkl, PHKEY phkRet,
LPDWORD lpdwDisposition )
{
CHAR szRegPath[ sizeof(IMM32_szRegKL)+16 ];
wsprintfA( szRegPath, "%s\\%08x", IMM32_szRegKL, (unsigned)hkl );
return RegCreateKeyExA( HKEY_LOCAL_MACHINE, szRegPath,
0, "REG_SZ",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL,
phkRet, lpdwDisposition );
}
static DWORD IMM32_GetIMEFileName( HKL hkl, LPSTR lpBuf, INT nBufLen )
{
HKEY hkey;
LONG nError;
DWORD dwType;
DWORD cbData;
CHAR szValueName[ sizeof(IMM32_szIME_File) ];
TRACE( "hkl = %08x\n", (unsigned)hkl );
nError = IMM32_RegOpenKey( hkl, &hkey );
if ( nError != ERROR_SUCCESS )
{
SetLastError( nError );
return 0;
}
memcpy( szValueName, IMM32_szIME_File, sizeof(IMM32_szIME_File) );
nError = RegQueryValueExA( hkey, szValueName, NULL,
&dwType, NULL, &cbData );
if ( nError == ERROR_SUCCESS && dwType != REG_SZ )
nError = ERROR_FILE_NOT_FOUND; /* FIXME? */
if ( nError == ERROR_SUCCESS && lpBuf != NULL && nBufLen != 0 )
{
if ( nBufLen < (INT)cbData )
nError = ERROR_INSUFFICIENT_BUFFER;
else
nError = RegQueryValueExA( hkey, szValueName, NULL,
&dwType, lpBuf, &cbData );
}
RegCloseKey( hkey );
if ( nError != ERROR_SUCCESS )
{
SetLastError( nError );
return 0;
}
return cbData;
}
static
BOOL IMM32_GetIMEHandlersA( HINSTANCE hInstIME,
struct IMM32_IME_EXPORTED_HANDLERS* phandlers )
{
BOOL fError;
#define FE(name) \
phandlers->p##name = (IMM32_p##name) \
GetProcAddress(hInstIME,#name); \
if ( phandlers->p##name == NULL ) fError = TRUE;
#define FE_(name) \
phandlers->p##name.A = (IMM32_p##name##A) \
GetProcAddress(hInstIME,#name); \
if ( phandlers->p##name.A == NULL ) fError = TRUE;
fError = FALSE;
FE_(ImeInquire)
FE_(ImeConfigure)
FE_(ImeConversionList)
FE(ImeDestroy)
FE_(ImeEnumRegisterWord)
FE_(ImeGetRegisterWordStyle)
FE_(ImeEscape)
FE(ImeProcessKey)
FE_(ImeRegisterWord)
FE(ImeSelect)
FE(ImeSetActiveContext)
FE_(ImeSetCompositionString)
FE(ImeToAsciiEx)
FE_(ImeUnregisterWord)
FE(NotifyIME)
if ( fError )
return FALSE;
FE_(ImeGetImeMenuItems)
#undef FE
#undef FE_
return TRUE;
}
static
BOOL IMM32_GetIMEHandlersW( HINSTANCE hInstIME,
struct IMM32_IME_EXPORTED_HANDLERS* phandlers )
{
BOOL fError;
#define FE(name) \
phandlers->p##name = (IMM32_p##name) \
GetProcAddress(hInstIME,#name); \
if ( phandlers->p##name == NULL ) fError = TRUE;
#define FE_(name) \
phandlers->p##name.W = (IMM32_p##name##W) \
GetProcAddress(hInstIME,#name); \
if ( phandlers->p##name.W == NULL ) fError = TRUE;
fError = FALSE;
FE_(ImeInquire)
FE_(ImeConfigure)
FE_(ImeConversionList)
FE(ImeDestroy)
FE_(ImeEnumRegisterWord)
FE_(ImeGetRegisterWordStyle)
FE_(ImeEscape)
FE(ImeProcessKey)
FE_(ImeRegisterWord)
FE(ImeSelect)
FE(ImeSetActiveContext)
FE_(ImeSetCompositionString)
FE(ImeToAsciiEx)
FE_(ImeUnregisterWord)
FE(NotifyIME)
if ( fError )
return FALSE;
FE_(ImeGetImeMenuItems)
#undef FE
#undef FE_
return TRUE;
}
static IMM32_IMEKL* IMM32_LoadIME( HKL hkl )
{
IMM32_IMEKL* pkl = NULL;
BOOL fInitialized = FALSE;
CHAR* pszFileName = NULL;
DWORD dwBufLen;
IMM32_pImeInquireA pImeInquire;
IMM32_pImeDestroy pImeDestroy = NULL;
CHAR szUIClassName[ (IMM32_UICLASSNAME_MAX+1)*sizeof(WCHAR) ];
dwBufLen = IMM32_GetIMEFileName( hkl, NULL, 0 );
if ( dwBufLen == 0 )
goto err;
pszFileName = (CHAR*)IMM32_HeapAlloc( 0, sizeof(CHAR)*(dwBufLen+1) );
if ( pszFileName == NULL )
{
SetLastError( ERROR_OUTOFMEMORY );
goto err;
}
if ( !IMM32_GetIMEFileName( hkl, pszFileName, dwBufLen + 1 ) )
goto err;
pkl = (IMM32_IMEKL*)
IMM32_HeapAlloc( HEAP_ZERO_MEMORY, sizeof(IMM32_IMEKL) );
if ( pkl == NULL )
{
SetLastError( ERROR_OUTOFMEMORY );
goto err;
}
pkl->pNext = NULL;
pkl->hkl = hkl;
pkl->hInstIME = LoadLibraryA( pszFileName );
if ( pkl->hInstIME == (HINSTANCE)NULL )
goto err;
pImeInquire = (IMM32_pImeInquireA)GetProcAddress
( pkl->hInstIME, "ImeInquire" );
pImeDestroy = (IMM32_pImeDestroy)GetProcAddress
( pkl->hInstIME, "ImeDestroy" );
if ( pImeInquire == NULL || pImeDestroy == NULL )
goto err;
if ( !pImeInquire( &(pkl->imeinfo), szUIClassName, NULL ) )
{
SetLastError( ERROR_DLL_INIT_FAILED ); /* FIXME? */
goto err;
}
fInitialized = TRUE;
/* FIXME: Is this correct??? */
if ( pkl->imeinfo.fdwProperty & IME_PROP_UNICODE )
pkl->fUnicode = TRUE;
else
pkl->fUnicode = FALSE;
if ( pkl->fUnicode )
{
if ( !IMM32_GetIMEHandlersW( pkl->hInstIME, &pkl->handlers ) )
goto err;
memcpy( pkl->UIClassName.W, szUIClassName,
IMM32_UICLASSNAME_MAX*sizeof(WCHAR) );
TRACE( "UI class name(Unicode): %s\n",
debugstr_w(pkl->UIClassName.W) );
}
else
{
if ( !IMM32_GetIMEHandlersA( pkl->hInstIME, &pkl->handlers ) )
goto err;
memcpy( pkl->UIClassName.A, szUIClassName,
IMM32_UICLASSNAME_MAX*sizeof(CHAR) );
TRACE( "UI class name(ASCII): %s\n",
debugstr_a(pkl->UIClassName.A) );
}
/* The IME is loaded successfully. */
pkl->pszIMEFileName = pszFileName; pszFileName = NULL;
return pkl;
err:
IMM32_HeapFree( pszFileName );
if ( pkl != NULL )
{
if ( pkl->hInstIME != (HINSTANCE)NULL )
{
if ( fInitialized )
(void)pImeDestroy(0);
FreeLibrary( pkl->hInstIME );
}
IMM32_HeapFree( pkl );
}
return NULL;
}
const IMM32_IMEKL* IMM32_GetIME( HKL hkl )
{
IMM32_IMEKL* pkl;
IMM32_Lock();
pkl = IMM32_pklFirst;
while ( pkl != NULL )
{
if ( pkl->hkl == hkl )
goto end;
pkl = pkl->pNext;
}
pkl = IMM32_LoadIME( hkl );
if ( pkl != NULL )
{
pkl->pNext = IMM32_pklFirst;
IMM32_pklFirst = pkl;
}
end:
IMM32_Unlock();
return pkl;
}
void IMM32_UnloadAllIMEs( void )
{
IMM32_IMEKL* pkl;
IMM32_IMEKL* pklNext;
IMM32_Lock();
pkl = IMM32_pklFirst;
while ( pkl != NULL )
{
TRACE( "hkl = %08x\n", (unsigned)pkl->hkl );
pklNext = pkl->pNext;
(void)pkl->handlers.pImeDestroy(0);
FreeLibrary( pkl->hInstIME );
IMM32_HeapFree( pkl->pszIMEFileName );
IMM32_HeapFree( pkl );
pkl = pklNext;
}
IMM32_pklFirst = NULL;
IMM32_Unlock();
}
/***********************************************************************
* ImmInstallIMEA (IMM32.@)
*/
HKL WINAPI ImmInstallIMEA(
LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
{
HKL hkl;
DWORD dwLCID;
DWORD dwTryCount;
LONG nError;
HKEY hkey;
DWORD dwDisposition;
DWORD cbData;
CHAR szValueName[ sizeof(IMM32_szIME_File) ];
TRACE("(%s, %s)\n",
debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText) );
dwLCID = (DWORD)GetThreadLocale();
dwTryCount = 0;
FIXME( "IMEs don't work correctly now since\n"
"wine/windows/input.c doesn't handle HKL correctly.\n" );
while ( 1 )
{
hkl = (HKL)(((0xe000|dwTryCount)<<16) | (dwLCID));
nError = IMM32_RegCreateKey( hkl, &hkey, &dwDisposition );
if ( nError != ERROR_SUCCESS )
break;
memcpy( szValueName, IMM32_szIME_File,
sizeof(IMM32_szIME_File) );
nError = RegQueryValueExA( hkey, szValueName, NULL,
NULL, NULL, &cbData );
if ( nError == ERROR_SUCCESS && cbData > 0 )
{
RegCloseKey( hkey );
/* try to assign an other HKL. */
dwTryCount ++;
if ( dwTryCount >= 0x100 )
{
nError = ERROR_ACCESS_DENIED; /* FIXME */
break;
}
continue;
}
nError = RegSetValueExA( hkey, IMM32_szIME_File, 0,
REG_SZ, lpszIMEFileName,
strlen(lpszIMEFileName)+1 );
if ( nError == ERROR_SUCCESS )
nError = RegSetValueExA( hkey, IMM32_szLayout_File, 0,
REG_SZ, lpszLayoutText,
strlen(lpszLayoutText)+1 );
RegCloseKey( hkey );
break;
}
if ( nError != ERROR_SUCCESS )
{
SetLastError( nError );
return (HKL)NULL;
}
return hkl;
}
/***********************************************************************
* ImmInstallIMEW (IMM32.@)
*/
HKL WINAPI ImmInstallIMEW(
LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
{
LPSTR lpszParam1;
LPSTR lpszParam2;
HKL hkl;
TRACE("(%s, %s)\n",
debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText) );
lpszParam1 = IMM32_strdupWtoA( lpszIMEFileName );
lpszParam2 = IMM32_strdupWtoA( lpszLayoutText );
if ( ( lpszParam1 == NULL ) || ( lpszParam2 == NULL ) )
{
SetLastError( ERROR_OUTOFMEMORY );
hkl = (HKL)NULL;
}
else
{
hkl = ImmInstallIMEA( lpszParam1, lpszParam2 );
}
IMM32_HeapFree( lpszParam1 );
IMM32_HeapFree( lpszParam2 );
return hkl;
}
/***********************************************************************
* ImmIsIME (IMM32.@)
*/
BOOL WINAPI ImmIsIME(HKL hkl)
{
const IMM32_IMEKL* pkl;
TRACE("(0x%08x)\n", hkl);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return FALSE;
return TRUE;
}
/***********************************************************************
* ImmGetIMEFileNameA (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameA(HKL hkl, LPSTR lpszFileName, UINT uBufLen)
{
const IMM32_IMEKL* pkl;
UINT uIMEFileNameLen;
TRACE("(%08x,%p,%u)\n",hkl,lpszFileName,uBufLen);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
uIMEFileNameLen = strlen(pkl->pszIMEFileName);
if ( uBufLen == 0 )
return uIMEFileNameLen;
if ( uBufLen <= uIMEFileNameLen )
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
memcpy( lpszFileName, pkl->pszIMEFileName,
sizeof(CHAR)*(uIMEFileNameLen+1) );
return uIMEFileNameLen;
}
/***********************************************************************
* ImmGetIMEFileNameW (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameW(HKL hkl, LPWSTR lpszFileName, UINT uBufLen)
{
const IMM32_IMEKL* pkl;
UINT uIMEFileNameLen;
TRACE("(%08x,%p,%u)\n",hkl,lpszFileName,uBufLen);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
uIMEFileNameLen = IMM32_strlenAtoW(pkl->pszIMEFileName);
if ( uBufLen == 0 )
return uIMEFileNameLen;
if ( uBufLen <= uIMEFileNameLen )
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
IMM32_strncpyAtoW( lpszFileName, pkl->pszIMEFileName, uBufLen );
return uIMEFileNameLen;
}
/***********************************************************************
* ImmGetProperty (IMM32.@)
*/
DWORD WINAPI ImmGetProperty(HKL hkl, DWORD fdwIndex)
{
const IMM32_IMEKL* pkl;
DWORD dwRet;
TRACE("(0x%08x, %ld)\n", hkl, fdwIndex);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
switch ( fdwIndex )
{
case IGP_GETIMEVERSION:
dwRet = IMEVER_0400;
break;
case IGP_PROPERTY:
dwRet = pkl->imeinfo.fdwProperty;
break;
case IGP_CONVERSION:
dwRet = pkl->imeinfo.fdwConversionCaps;
break;
case IGP_SENTENCE:
dwRet = pkl->imeinfo.fdwSentenceCaps;
break;
case IGP_UI:
dwRet = pkl->imeinfo.fdwUICaps;
break;
case IGP_SETCOMPSTR:
dwRet = pkl->imeinfo.fdwSCSCaps;
break;
case IGP_SELECT:
dwRet = pkl->imeinfo.fdwSelectCaps;
break;
default:
FIXME("(0x%08x, %ld): invalid/unknown property.\n",
hkl, fdwIndex);
SetLastError( ERROR_INVALID_PARAMETER );
dwRet = 0;
}
return dwRet;
}
/***********************************************************************
* ImmEnumRegisterWordA (IMM32.@)
*/
UINT WINAPI ImmEnumRegisterWordA(
HKL hkl, REGISTERWORDENUMPROCA lpfnEnumProc,
LPCSTR lpszReading, DWORD dwStyle,
LPCSTR lpszRegister, LPVOID lpData)
{
const IMM32_IMEKL* pkl;
TRACE("(0x%08x, %p, %s, %ld, %s, %p)\n",
hkl, lpfnEnumProc,
debugstr_a(lpszReading), dwStyle,
debugstr_a(lpszRegister), lpData);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
if ( pkl->fUnicode )
{
FIXME( "please implement UNICODE->ANSI\n" );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
else
{
return pkl->handlers.pImeEnumRegisterWord.A
( lpfnEnumProc, lpszReading, dwStyle,
lpszRegister, lpData );
}
}
/***********************************************************************
* ImmEnumRegisterWordW (IMM32.@)
*/
UINT WINAPI ImmEnumRegisterWordW(
HKL hkl, REGISTERWORDENUMPROCW lpfnEnumProc,
LPCWSTR lpszReading, DWORD dwStyle,
LPCWSTR lpszRegister, LPVOID lpData)
{
const IMM32_IMEKL* pkl;
TRACE("(0x%08x, %p, %s, %ld, %s, %p): stub\n",
hkl, lpfnEnumProc,
debugstr_w(lpszReading), dwStyle,
debugstr_w(lpszRegister), lpData);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
if ( pkl->fUnicode )
{
return pkl->handlers.pImeEnumRegisterWord.W
( lpfnEnumProc, lpszReading, dwStyle,
lpszRegister, lpData );
}
else
{
FIXME( "please implement ANSI->UNICODE\n" );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
}
/***********************************************************************
* ImmGetRegisterWordStyleA (IMM32.@)
*/
UINT WINAPI ImmGetRegisterWordStyleA(
HKL hkl, UINT nItem, LPSTYLEBUFA lpStyleBuf)
{
const IMM32_IMEKL* pkl;
TRACE("(0x%08x, %d, %p)\n", hkl, nItem, lpStyleBuf);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
if ( pkl->fUnicode )
{
FIXME( "please implement UNICODE->ANSI\n" );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
else
{
return pkl->handlers.pImeGetRegisterWordStyle.A
( nItem, lpStyleBuf );
}
}
/***********************************************************************
* ImmGetRegisterWordStyleW (IMM32.@)
*/
UINT WINAPI ImmGetRegisterWordStyleW(
HKL hkl, UINT nItem, LPSTYLEBUFW lpStyleBuf)
{
const IMM32_IMEKL* pkl;
TRACE("(0x%08x, %d, %p)\n", hkl, nItem, lpStyleBuf);
pkl = IMM32_GetIME( hkl );
if ( pkl == NULL )
return 0;
if ( pkl->fUnicode )
{
return pkl->handlers.pImeGetRegisterWordStyle.W
( nItem, lpStyleBuf );
}
else
{
FIXME( "please implement ANSI->UNICODE\n" );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
}

View File

@ -23,16 +23,126 @@ DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
#define IMM32_CONVERSION_BUFSIZE 200
static CHAR IMM32_szIMEClass[] = "IME";
static CHAR IMM32_szIMEWindowName[] = "Default IME";
typedef struct
{
int dummy;
HWND hwndSelf;
HWND hwndActive;
DWORD dwBufUsed;
union
{
CHAR A[IMM32_CONVERSION_BUFSIZE];
WCHAR W[IMM32_CONVERSION_BUFSIZE];
} buf;
} IMM32_IMEWNDPARAM;
static BOOL IMM32_IsUIMessage( UINT nMsg );
static
LRESULT IMM32_IMEWnd_WM_KEYDOWN( IMM32_IMEWNDPARAM* pParam,
WPARAM wParam, LPARAM lParam )
{
BYTE bKeyState[ 256 ];
DWORD dwTransBufSize;
UINT nNumOfMsg;
LRESULT lr;
HIMC hIMC;
IMM32_IMC* pIMC;
const IMM32_IMEKL* pkl;
if ( pParam->hwndActive == (HWND)NULL )
return 0;
/* get context -> get pkl. */
hIMC = ImmGetContext( pParam->hwndActive );
if ( hIMC == NULLIMC )
return 0;
pIMC = IMM32_LockIMC( hIMC );
if ( pIMC == NULL )
{
ImmReleaseContext( pParam->hwndActive, hIMC );
return 0;
}
pkl = pIMC->pkl;
GetKeyboardState( bKeyState );
if ( !pkl->handlers.pImeProcessKey
( hIMC, wParam, lParam, bKeyState ) )
{
lr = SendMessageA( pParam->hwndActive, WM_IME_KEYDOWN,
wParam, lParam );
goto end;
}
dwTransBufSize = 0;
nNumOfMsg = pkl->handlers.pImeToAsciiEx
( wParam, (lParam>>16)&0xff,
bKeyState, &dwTransBufSize,
0, /* FIXME!!! - 1 if a menu is active */
hIMC );
/* FIXME - process generated messages */
/* I cannot use ImmGenerateMessage() since
* the IME window must handle generated messages. */
/* NOTE - I must check pkl->fUnicode. */
FIXME( "%d messages generated.\n", nNumOfMsg );
lr = 0;
end:
IMM32_UnlockIMC( hIMC );
ImmReleaseContext( pParam->hwndActive, hIMC );
return lr;
}
static
LRESULT IMM32_IMEWnd_WM_KEYUP( IMM32_IMEWNDPARAM* pParam,
WPARAM wParam, LPARAM lParam )
{
BYTE bKeyState[ 256 ];
LRESULT lr;
HIMC hIMC;
IMM32_IMC* pIMC;
const IMM32_IMEKL* pkl;
if ( pParam->hwndActive == (HWND)NULL )
return 0;
/* get context -> get pkl. */
hIMC = ImmGetContext( pParam->hwndActive );
if ( hIMC == NULLIMC )
return 0;
pIMC = IMM32_LockIMC( hIMC );
if ( pIMC == NULL )
{
ImmReleaseContext( pParam->hwndActive, hIMC );
return 0;
}
pkl = pIMC->pkl;
GetKeyboardState( bKeyState );
if ( !pkl->handlers.pImeProcessKey
( hIMC, wParam, lParam, bKeyState ) )
{
lr = SendMessageA( pParam->hwndActive, WM_IME_KEYUP,
wParam, lParam );
goto end;
}
lr = 0;
end:
IMM32_UnlockIMC( hIMC );
ImmReleaseContext( pParam->hwndActive, hIMC );
return lr;
}
static
LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
@ -49,13 +159,16 @@ LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
return -1L;
SetWindowLongA( hwnd, 0L, (LONG)pParam );
/* FIXME - Initialize pParam. */
/* Initialize pParam. */
pParam->hwndSelf = hwnd;
pParam->hwndActive = (HWND)NULL;
pParam->dwBufUsed = 0;
return 0;
}
else if ( nMsg == WM_DESTROY )
{
/* FIXME - Uninitialize pParam. */
/* Uninitialize pParam. */
IMM32_HeapFree( pParam );
SetWindowLongA( hwnd, 0L, (LONG)NULL );
@ -71,8 +184,40 @@ LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
/* FIXME - handle all messages. */
/* FIXME - handle all notifications. */
if ( IMM32_IsUIMessage( nMsg ) )
switch ( nMsg )
{
case WM_KEYDOWN:
return IMM32_IMEWnd_WM_KEYDOWN( pParam, wParam, lParam );
case WM_KEYUP:
return IMM32_IMEWnd_WM_KEYUP( pParam, wParam, lParam );
case WM_IME_KEYDOWN:
ERR( "Why WM_IME_KEYDOWN is generated?" );
return 0;
case WM_IME_KEYUP:
ERR( "Why WM_IME_KEYUP is generated?" );
return 0;
case WM_IME_CHAR:
FIXME( "ignore WM_IME_CHAR - wParam %08x, lParam %08lx.\n",
wParam, lParam );
return 0;
case WM_CHAR:
/* TranslateMessage don't support IME HKL. - FIXME? */
FIXME( "ignore WM_CHAR - wParam %08x, lParam %08lx.\n",
wParam, lParam );
return 0;
case WM_IME_CONTROL:
case WM_IME_REQUEST:
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_SETCONTEXT:
case WM_IME_NOTIFY:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
FIXME( "handle message %08x\n", nMsg );
return 0;
}
return DefWindowProcA( hwnd, nMsg, wParam, lParam );
}
@ -91,9 +236,9 @@ BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL )
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(LONG);
wc.hInstance = hInstDLL;
wc.hIcon = LoadIconA((HINSTANCE)NULL,IDI_APPLICATIONA);
wc.hCursor = LoadCursorA((HINSTANCE)NULL,IDC_IBEAMA);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* FIXME? */
wc.hIcon = (HICON)NULL;
wc.hCursor = LoadCursorA((HINSTANCE)NULL,IDC_ARROWA);
wc.hbrBackground = (HBRUSH)NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = IMM32_szIMEClass;
if ( !RegisterClassA( &wc ) )
@ -110,7 +255,22 @@ void IMM32_UnregisterIMEWndClass( HINSTANCE hInstDLL )
(void)UnregisterClassA( IMM32_szIMEClass, hInstDLL );
}
/***********************************************************************
* IMM32_CreateDefaultIMEWnd (internal)
*/
HWND IMM32_CreateDefaultIMEWnd( void )
{
return CreateWindowExA( 0L,
IMM32_szIMEClass,
IMM32_szIMEWindowName,
WS_POPUP | WS_CLIPSIBLINGS | WS_OVERLAPPED,
0, 0, 0, 0,
(HWND)NULL,
(HMENU)NULL,
(HINSTANCE)GetModuleHandleA(NULL),
NULL );
}
static BOOL IMM32_IsUIMessage( UINT nMsg )
{

View File

@ -50,60 +50,6 @@ BOOL WINAPI ImmConfigureIMEW(
return FALSE;
}
/***********************************************************************
* ImmCreateContext (IMM32.@)
*/
HIMC WINAPI ImmCreateContext()
{
FIXME("(): stub\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return (HIMC)NULL;
}
/***********************************************************************
* ImmDestroyContext (IMM32.@)
*/
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
{
FIXME("(0x%08x): stub\n",hIMC);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* ImmEnumRegisterWordA (IMM32.@)
*/
UINT WINAPI ImmEnumRegisterWordA(
HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc,
LPCSTR lpszReading, DWORD dwStyle,
LPCSTR lpszRegister, LPVOID lpData)
{
FIXME("(0x%08x, %p, %s, %ld, %s, %p): stub\n",
hKL, lpfnEnumProc,
debugstr_a(lpszReading), dwStyle,
debugstr_a(lpszRegister), lpData
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmEnumRegisterWordW (IMM32.@)
*/
UINT WINAPI ImmEnumRegisterWordW(
HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
LPCWSTR lpszReading, DWORD dwStyle,
LPCWSTR lpszRegister, LPVOID lpData)
{
FIXME("(0x%08x, %p, %s, %ld, %s, %p): stub\n",
hKL, lpfnEnumProc,
debugstr_w(lpszReading), dwStyle,
debugstr_w(lpszRegister), lpData
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmEscapeA (IMM32.@)
*/
@ -383,32 +329,6 @@ DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBu
return 0;
}
/***********************************************************************
* ImmGetIMEFileNameA (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameA(
HKL hKL, LPSTR lpszFileName, UINT uBufLen)
{
FIXME("(0x%08x, %s, %d): stub\n",
hKL, debugstr_a(lpszFileName), uBufLen
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmGetIMEFileNameW (IMM32.@)
*/
UINT WINAPI ImmGetIMEFileNameW(
HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
{
FIXME("(0x%08x, %s, %d): stub\n",
hKL, debugstr_w(lpszFileName), uBufLen
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmGetOpenStatus (IMM32.@)
*/
@ -419,38 +339,6 @@ BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
return FALSE;
}
/***********************************************************************
* ImmGetProperty (IMM32.@)
*/
DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
{
FIXME("(0x%08x, %ld): stub\n", hKL, fdwIndex);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmGetRegisterWordStyleA (IMM32.@)
*/
UINT WINAPI ImmGetRegisterWordStyleA(
HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf)
{
FIXME("(0x%08x, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmGetRegisterWordStyleW (IMM32.@)
*/
UINT WINAPI ImmGetRegisterWordStyleW(
HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf)
{
FIXME("(0x%08x, %d, %p): stub\n", hKL, nItem, lpStyleBuf);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmGetStatusWindowPos (IMM32.@)
*/
@ -482,42 +370,6 @@ UINT WINAPI ImmGetVirtualKey(HWND hWnd)
}
}
/***********************************************************************
* ImmInstallIMEA (IMM32.@)
*/
HKL WINAPI ImmInstallIMEA(
LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText)
{
FIXME("(%s, %s): stub\n",
debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return (HKL)NULL;
}
/***********************************************************************
* ImmInstallIMEW (IMM32.@)
*/
HKL WINAPI ImmInstallIMEW(
LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
{
FIXME("(%s, %s): stub\n",
debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText)
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return (HKL)NULL;
}
/***********************************************************************
* ImmIsIME (IMM32.@)
*/
BOOL WINAPI ImmIsIME(HKL hKL)
{
FIXME("(0x%08x): stub\n", hKL);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* ImmNotifyIME (IMM32.@)
*/
@ -708,36 +560,6 @@ BOOL WINAPI ImmUnregisterWordW(
return FALSE;
}
/***********************************************************************
* ImmLockIMC (IMM32.@)
*/
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
FIXME("(0x%08x): stub\n", (unsigned)hIMC);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}
/***********************************************************************
* ImmUnlockIMC (IMM32.@)
*/
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
FIXME("(0x%08x): stub\n", (unsigned)hIMC);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* ImmGetIMCLockCount (IMM32.@)
*/
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
FIXME("(0x%08x): stub\n", (unsigned)hIMC);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/***********************************************************************
* ImmCreateSoftKeyboard (IMM32.@)
*/

View File

@ -5,6 +5,7 @@ init IMM32_DllMain
import user32.dll
# NOTE: gdi32.dll will be required for implementing IME global class.
import gdi32.dll
import advapi32.dll
import kernel32.dll
import ntdll.dll

View File

@ -118,6 +118,36 @@ struct IMM32_IME_EXPORTED_HANDLERS
} pImeGetImeMenuItems;
};
typedef struct IMM32_tagIMEKL IMM32_IMEKL;
typedef struct IMM32_tagIMC IMM32_IMC;
/* Win9x DDK says the UI class name can be up to 16 TCHARs. */
#define IMM32_UICLASSNAME_MAX 16
struct IMM32_tagIMEKL
{
IMM32_IMEKL* pNext;
HKL hkl;
BOOL fUnicode;
HINSTANCE hInstIME;
LPSTR pszIMEFileName;
IMEINFO imeinfo;
struct IMM32_IME_EXPORTED_HANDLERS handlers;
union
{
CHAR A[IMM32_UICLASSNAME_MAX];
WCHAR W[IMM32_UICLASSNAME_MAX];
} UIClassName;
};
struct IMM32_tagIMC
{
INPUTCONTEXT context;
const IMM32_IMEKL* pkl;
BOOL fSelected;
};
@ -126,6 +156,10 @@ LPVOID IMM32_HeapAlloc( DWORD dwFlags, DWORD dwSize );
LPVOID IMM32_HeapReAlloc( DWORD dwFlags, LPVOID lpv, DWORD dwSize );
void IMM32_HeapFree( LPVOID lpv );
IMM32_THREADDATA* IMM32_GetThreadData( void );
HIMC IMM32_GetDefaultContext( void );
HWND IMM32_GetDefaultIMEWnd( void );
void IMM32_Lock( void );
void IMM32_Unlock( void );
/* memory.c */
IMM32_MOVEABLEMEM* IMM32_MoveableAlloc( DWORD dwHeapFlags, DWORD dwHeapSize );
@ -148,5 +182,14 @@ LPSTR IMM32_strdupWtoA( LPCWSTR lpwstr );
/* imewnd.c */
BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL );
void IMM32_UnregisterIMEWndClass( HINSTANCE hInstDLL );
HWND IMM32_CreateDefaultIMEWnd( void );
/* imekl.c */
const IMM32_IMEKL* IMM32_GetIME( HKL hkl );
void IMM32_UnloadAllIMEs( void );
/* imc.c */
IMM32_IMC* IMM32_LockIMC( HIMC hIMC );
BOOL IMM32_UnlockIMC( HIMC hIMC );

View File

@ -51,7 +51,7 @@ BOOL WINAPI IMM32_DllMain(
IMM32_RegisterIMEWndClass( hInstDLL );
break;
case DLL_PROCESS_DETACH:
/*IMM32_UnloadAllIMEs();*/
IMM32_UnloadAllIMEs();
IMM32_UnregisterIMEWndClass( hInstDLL );
IMM32_CleanupProcessMem();
@ -171,3 +171,39 @@ IMM32_THREADDATA* IMM32_GetThreadData( void )
return pData;
}
HIMC IMM32_GetDefaultContext( void )
{
IMM32_THREADDATA* pData;
pData = IMM32_GetThreadData();
if ( pData == NULL )
return NULLIMC;
if ( pData->hIMC == NULLIMC )
pData->hIMC = ImmCreateContext();
return pData->hIMC;
}
HWND IMM32_GetDefaultIMEWnd( void )
{
IMM32_THREADDATA* pData;
pData = IMM32_GetThreadData();
if ( pData == NULL )
return NULLIMC;
if ( pData->hwndIME == (HWND)NULL )
pData->hwndIME = IMM32_CreateDefaultIMEWnd();
return pData->hwndIME;
}
void IMM32_Lock( void )
{
EnterCriticalSection( &IMM32_csIMM );
}
void IMM32_Unlock( void )
{
LeaveCriticalSection( &IMM32_csIMM );
}