Commit 8ad2676d authored by Hidenori Takeshima's avatar Hidenori Takeshima Committed by Alexandre Julliard

Removed some code because of MS EULA concerns.

Rewrote stubs.
parent f596eceb
......@@ -9,13 +9,7 @@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
imc.c \
imekl.c \
imewnd.c \
imm.c \
main.c \
memory.c \
string.c
imm.c
@MAKE_DLL_RULES@
......
/*
* Input Method Context
*
* Copyright 2000 Hidenori Takeshima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"
#include "wine/debug.h"
WINE_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!\n" );
}
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 );
}
/*
* Implementation of the 'IME window' class
*
* Copyright 2000 Hidenori Takeshima
*
*
* FIXME:
* - handle all messages.
* - handle all notifications.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"
#include "wine/debug.h"
WINE_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
{
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,
WPARAM wParam, LPARAM lParam )
{
IMM32_IMEWNDPARAM* pParam =
(IMM32_IMEWNDPARAM*)GetWindowLongA( hwnd, 0L );
if ( nMsg == WM_CREATE )
{
pParam = (IMM32_IMEWNDPARAM*)IMM32_HeapAlloc(
HEAP_ZERO_MEMORY, sizeof(IMM32_IMEWNDPARAM) );
if ( pParam == NULL )
return -1L;
SetWindowLongA( hwnd, 0L, (LONG)pParam );
/* Initialize pParam. */
pParam->hwndSelf = hwnd;
pParam->hwndActive = (HWND)NULL;
pParam->dwBufUsed = 0;
return 0;
}
else if ( nMsg == WM_DESTROY )
{
/* Uninitialize pParam. */
IMM32_HeapFree( pParam );
SetWindowLongA( hwnd, 0L, (LONG)NULL );
return 0;
}
if ( pParam == NULL )
{
if ( IMM32_IsUIMessage( nMsg ) )
return 0;
return DefWindowProcA( hwnd, nMsg, wParam, lParam );
}
/* FIXME - handle all messages. */
/* FIXME - handle all notifications. */
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?\n" );
return 0;
case WM_IME_KEYUP:
ERR( "Why WM_IME_KEYUP is generated?\n" );
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 );
}
/***********************************************************************
* IMM32_RegisterClass (internal)
*/
BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL )
{
WNDCLASSA wc;
/* SDK says the "IME" window class is a system global class. */
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = IMM32_IMEWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(LONG);
wc.hInstance = hInstDLL;
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 ) )
return FALSE;
return TRUE;
}
/***********************************************************************
* IMM32_UnregisterClass (internal)
*/
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 )
{
switch ( nMsg )
{
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. */
return TRUE;
}
return FALSE;
}
/***********************************************************************
* ImmIsUIMessageA (IMM32.@)
*/
BOOL WINAPI ImmIsUIMessageA(
HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
TRACE("(0x%08x, %d, %d, %ld)\n",
hwndIME, msg, wParam, lParam);
if ( !IMM32_IsUIMessage( msg ) )
return FALSE;
if ( hwndIME == (HWND)NULL )
return TRUE;
switch ( msg )
{
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:
SendMessageA( hwndIME, msg, wParam, lParam );
break;
case 0x287: /* What is this message? */
FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
hwndIME, msg, wParam, lParam);
SendMessageA( hwndIME, msg, wParam, lParam );
break;
}
return TRUE;
}
/***********************************************************************
* ImmIsUIMessageW (IMM32.@)
*/
BOOL WINAPI ImmIsUIMessageW(
HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
TRACE("(0x%08x, %d, %d, %ld)\n",
hwndIME, msg, wParam, lParam);
if ( !IMM32_IsUIMessage( msg ) )
return FALSE;
if ( hwndIME == (HWND)NULL )
return TRUE;
switch ( msg )
{
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:
SendMessageW( hwndIME, msg, wParam, lParam );
break;
case 0x287: /* What is this message? */
FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
hwndIME, msg, wParam, lParam);
SendMessageW( hwndIME, msg, wParam, lParam );
break;
}
return TRUE;
}
/*
* private header for implementing IMM.
*
* Copyright 2000 Hidenori Takeshima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
typedef struct IMM32_tagTHREADDATA IMM32_THREADDATA;
struct IMM32_tagTHREADDATA
{
HWND hwndIME;
HIMC hIMC;
};
typedef struct IMM32_tagMOVEABLEMEM IMM32_MOVEABLEMEM;
/* IME APIs */
typedef BOOL (WINAPI *IMM32_pImeInquireA)(LPIMEINFO, LPSTR, LPCSTR);
typedef BOOL (WINAPI *IMM32_pImeInquireW)(LPIMEINFO, LPWSTR, LPCWSTR);
typedef BOOL (WINAPI *IMM32_pImeConfigureA)(HKL, HWND, DWORD, LPVOID);
typedef BOOL (WINAPI *IMM32_pImeConfigureW)(HKL, HWND, DWORD, LPVOID);
typedef DWORD (WINAPI *IMM32_pImeConversionListA)
(HIMC, LPCSTR, LPCANDIDATELIST, DWORD, UINT);
typedef DWORD (WINAPI *IMM32_pImeConversionListW)
(HIMC, LPCWSTR, LPCANDIDATELIST, DWORD, UINT);
typedef BOOL (WINAPI *IMM32_pImeDestroy)(UINT);
typedef UINT (WINAPI *IMM32_pImeEnumRegisterWordA)
(REGISTERWORDENUMPROCA, LPCSTR, DWORD, LPCSTR, LPVOID);
typedef UINT (WINAPI *IMM32_pImeEnumRegisterWordW)
(REGISTERWORDENUMPROCW, LPCWSTR, DWORD, LPCWSTR, LPVOID);
typedef UINT (WINAPI *IMM32_pImeGetRegisterWordStyleA)(UINT, LPSTYLEBUFA);
typedef UINT (WINAPI *IMM32_pImeGetRegisterWordStyleW)(UINT, LPSTYLEBUFW);
typedef LRESULT (WINAPI *IMM32_pImeEscapeA)(HIMC, UINT, LPVOID);
typedef LRESULT (WINAPI *IMM32_pImeEscapeW)(HIMC, UINT, LPVOID);
typedef BOOL (WINAPI *IMM32_pImeProcessKey)(HIMC, UINT, LPARAM, CONST LPBYTE);
typedef BOOL (WINAPI *IMM32_pImeRegisterWordA)(LPCSTR, DWORD, LPCSTR);
typedef BOOL (WINAPI *IMM32_pImeRegisterWordW)(LPCWSTR, DWORD, LPCWSTR);
typedef BOOL (WINAPI *IMM32_pImeSelect)(HIMC, BOOL);
typedef BOOL (WINAPI *IMM32_pImeSetActiveContext)(HIMC, BOOL);
typedef BOOL (WINAPI *IMM32_pImeSetCompositionStringA)
(HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD);
typedef BOOL (WINAPI *IMM32_pImeSetCompositionStringW)
(HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD);
typedef UINT (WINAPI *IMM32_pImeToAsciiEx)
(UINT, UINT, CONST LPBYTE, LPDWORD, UINT, HIMC);
typedef BOOL (WINAPI *IMM32_pImeUnregisterWordA)(LPCSTR, DWORD, LPCSTR);
typedef BOOL (WINAPI *IMM32_pImeUnregisterWordW)(LPCWSTR, DWORD, LPCWSTR);
typedef BOOL (WINAPI *IMM32_pNotifyIME)(HIMC, DWORD, DWORD, DWORD);
/* for Win98 and later */
typedef DWORD (WINAPI *IMM32_pImeGetImeMenuItemsA)
(HIMC, DWORD, DWORD, LPIMEMENUITEMINFOA, LPIMEMENUITEMINFOA, DWORD);
typedef DWORD (WINAPI *IMM32_pImeGetImeMenuItemsW)
(HIMC, DWORD, DWORD, LPIMEMENUITEMINFOW, LPIMEMENUITEMINFOW, DWORD);
struct IMM32_IME_EXPORTED_HANDLERS
{
union
{
IMM32_pImeInquireA A;
IMM32_pImeInquireW W;
} pImeInquire;
union
{
IMM32_pImeConfigureA A;
IMM32_pImeConfigureW W;
} pImeConfigure;
union
{
IMM32_pImeConversionListA A;
IMM32_pImeConversionListW W;
} pImeConversionList;
IMM32_pImeDestroy pImeDestroy;
union
{
IMM32_pImeEnumRegisterWordA A;
IMM32_pImeEnumRegisterWordW W;
} pImeEnumRegisterWord;
union
{
IMM32_pImeGetRegisterWordStyleA A;
IMM32_pImeGetRegisterWordStyleW W;
} pImeGetRegisterWordStyle;
union
{
IMM32_pImeEscapeA A;
IMM32_pImeEscapeW W;
} pImeEscape;
IMM32_pImeProcessKey pImeProcessKey;
union
{
IMM32_pImeRegisterWordA A;
IMM32_pImeRegisterWordW W;
} pImeRegisterWord;
IMM32_pImeSelect pImeSelect;
IMM32_pImeSetActiveContext pImeSetActiveContext;
union
{
IMM32_pImeSetCompositionStringA A;
IMM32_pImeSetCompositionStringW W;
} pImeSetCompositionString;
IMM32_pImeToAsciiEx pImeToAsciiEx;
union
{
IMM32_pImeUnregisterWordA A;
IMM32_pImeUnregisterWordW W;
} pImeUnregisterWord;
IMM32_pNotifyIME pNotifyIME;
/* for Win98 and later */
union
{
IMM32_pImeGetImeMenuItemsA A;
IMM32_pImeGetImeMenuItemsW W;
} 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;
};
/* main.c */
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 );
void IMM32_MoveableFree( IMM32_MOVEABLEMEM* lpMoveable );
BOOL IMM32_MoveableReAlloc( IMM32_MOVEABLEMEM* lpMoveable,
DWORD dwHeapFlags, DWORD dwHeapSize );
LPVOID IMM32_MoveableLock( IMM32_MOVEABLEMEM* lpMoveable );
BOOL IMM32_MoveableUnlock( IMM32_MOVEABLEMEM* lpMoveable );
DWORD IMM32_MoveableGetLockCount( IMM32_MOVEABLEMEM* lpMoveable );
DWORD IMM32_MoveableGetSize( IMM32_MOVEABLEMEM* lpMoveable );
/* string.c */
INT IMM32_strlenAtoW( LPCSTR lpstr );
INT IMM32_strlenWtoA( LPCWSTR lpwstr );
LPWSTR IMM32_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen );
LPSTR IMM32_strncpyWtoA( LPSTR lpstr, LPCWSTR lpwstr, INT abuflen );
LPWSTR IMM32_strdupAtoW( LPCSTR lpstr );
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 );
......@@ -23,34 +23,6 @@
#include "imm.h"
#define NULLIMC ((HIMC)0)
/* offsets for WndExtra */
#define IMMGWL_IMC 0
#define IMMGWL_PRIVATE (sizeof(LONG))
/* INPUTCONTEXT.fdwInit */
#define INIT_STATUSWNDPOS 0x00000001
#define INIT_CONVERSION 0x00000002
#define INIT_SENTENCE 0x00000004
#define INIT_LOGFONT 0x00000008
#define INIT_COMPFORM 0x00000010
#define INIT_SOFTKBDPOS 0x00000020
/* IMEINFO.fdwProperty (low-order word) */
#define IME_PROP_END_UNLOAD 0x00000001
#define IME_PROP_KBD_CHAR_FIRST 0x00000002
#define IME_PROP_IGNORE_UPKEYS 0x00000004
#define IME_PROP_NEED_ALTKEY 0x00000008
#define IME_PROP_NO_KEYS_ON_CLOSE 0x00000010
/* IMEINFO.fdwProperty (high-order word) */
#define IME_PROP_AT_CARET 0x00010000
#define IME_PROP_SPECIAL_UI 0x00020000
#define IME_PROP_CANDLIST_START_FROM_1 0x00040000
#define IME_PROP_UNICODE 0x00080000
#define IME_PROP_COMPLETE_ON_UNSELECT 0x00100000
/*** IMM and IME Structures ***/
typedef struct tagINPUTCONTEXT {
......
/*
* The entry point of IMM32.DLL.
*
* Copyright 2000 Hidenori Takeshima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
static HANDLE IMM32_hHeap;
static DWORD IMM32_dwTLSIndex;
static CRITICAL_SECTION IMM32_csIMM;
static BOOL IMM32_InitProcessMem( void );
static void IMM32_CleanupProcessMem( void );
static void IMM32_InitThreadData( void );
static void IMM32_CleanupThreadData( void );
/***********************************************************************
* IMM32_DllMain
*/
BOOL WINAPI IMM32_DllMain(
HINSTANCE hInstDLL,
DWORD fdwReason,
LPVOID lpvReserved )
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
IMM32_InitProcessMem();
IMM32_RegisterIMEWndClass( hInstDLL );
break;
case DLL_PROCESS_DETACH:
IMM32_UnloadAllIMEs();
IMM32_UnregisterIMEWndClass( hInstDLL );
IMM32_CleanupProcessMem();
break;
case DLL_THREAD_ATTACH:
IMM32_InitThreadData();
break;
case DLL_THREAD_DETACH:
IMM32_CleanupThreadData();
break;
}
return TRUE;
}
static BOOL IMM32_InitProcessMem( void )
{
IMM32_hHeap = (HANDLE)NULL;
IMM32_dwTLSIndex = (DWORD)0xffffffff;
IMM32_hHeap = HeapCreate( 0, 0x10000, 0 );
if ( IMM32_hHeap == (HANDLE)NULL )
{
ERR( "cannot allocate heap for IMM32.\n" );
return FALSE;
}
IMM32_dwTLSIndex = TlsAlloc();
if ( IMM32_dwTLSIndex == (DWORD)0xffffffff )
{
ERR( "cannot allocate a TLS for IMM.\n" );
return FALSE;
}
InitializeCriticalSection( &IMM32_csIMM );
return TRUE;
}
static void IMM32_CleanupProcessMem( void )
{
DeleteCriticalSection( &IMM32_csIMM );
if ( IMM32_dwTLSIndex != (DWORD)0xffffffff )
{
TlsFree( IMM32_dwTLSIndex );
IMM32_dwTLSIndex = (DWORD)0xffffffff;
}
if ( IMM32_hHeap != (HANDLE)NULL )
{
(void)HeapDestroy( IMM32_hHeap );
IMM32_hHeap = (HANDLE)NULL;
}
}
LPVOID IMM32_HeapAlloc( DWORD dwFlags, DWORD dwSize )
{
return HeapAlloc( IMM32_hHeap, dwFlags, dwSize );
}
LPVOID IMM32_HeapReAlloc( DWORD dwFlags, LPVOID lpv, DWORD dwSize )
{
return HeapReAlloc( IMM32_hHeap, dwFlags, lpv, dwSize );
}
void IMM32_HeapFree( LPVOID lpv )
{
if ( lpv != NULL )
HeapFree( IMM32_hHeap, 0, lpv );
}
static void IMM32_InitThreadData( void )
{
TlsSetValue( IMM32_dwTLSIndex, NULL );
}
static void IMM32_CleanupThreadData( void )
{
IMM32_THREADDATA* pData;
pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
if ( pData != NULL )
{
/* Destroy Thread-local Data. */
if ( pData->hwndIME != (HWND)NULL )
DestroyWindow( pData->hwndIME );
if ( pData->hIMC != NULLIMC )
ImmDestroyContext( pData->hIMC );
IMM32_HeapFree( pData );
TlsSetValue( IMM32_dwTLSIndex, NULL );
}
}
IMM32_THREADDATA* IMM32_GetThreadData( void )
{
IMM32_THREADDATA* pData;
pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
if ( pData != NULL )
return pData;
pData = (IMM32_THREADDATA*)
IMM32_HeapAlloc( 0, sizeof(IMM32_THREADDATA) );
if ( pData == NULL )
return NULL;
/* Initialize Thread-local Data. */
pData->hwndIME = (HWND)NULL;
pData->hIMC = NULLIMC;
TlsSetValue( IMM32_dwTLSIndex, pData );
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 );
}
/*
* This file implements 'moveable' memory block.
*
* Copyright 2000 Hidenori Takeshima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
#define IMM32_MOVEABLEMEM_LOCK_MAX ((DWORD)0xffffffff)
struct IMM32_tagMOVEABLEMEM
{
DWORD dwLockCount;
DWORD dwSize;
LPVOID lpvMem;
};
IMM32_MOVEABLEMEM* IMM32_MoveableAlloc( DWORD dwHeapFlags, DWORD dwHeapSize )
{
IMM32_MOVEABLEMEM* lpMoveable;
lpMoveable = (IMM32_MOVEABLEMEM*)
IMM32_HeapAlloc( 0, sizeof( IMM32_MOVEABLEMEM ) );
if ( lpMoveable != NULL )
{
lpMoveable->dwLockCount = 0;
lpMoveable->dwSize = dwHeapSize;
lpMoveable->lpvMem = NULL;
if ( dwHeapSize > 0 )
{
lpMoveable->lpvMem =
IMM32_HeapAlloc( dwHeapFlags, dwHeapSize );
if ( lpMoveable->lpvMem == NULL )
{
IMM32_HeapFree( lpMoveable );
lpMoveable = NULL;
}
}
}
return lpMoveable;
}
void IMM32_MoveableFree( IMM32_MOVEABLEMEM* lpMoveable )
{
IMM32_HeapFree( lpMoveable->lpvMem );
IMM32_HeapFree( lpMoveable );
}
BOOL IMM32_MoveableReAlloc( IMM32_MOVEABLEMEM* lpMoveable,
DWORD dwHeapFlags, DWORD dwHeapSize )
{
LPVOID lpv;
if ( dwHeapSize > 0 )
{
if ( lpMoveable->dwLockCount > 0 )
dwHeapFlags |= HEAP_REALLOC_IN_PLACE_ONLY;
lpv = IMM32_HeapReAlloc( dwHeapFlags,
lpMoveable->lpvMem, dwHeapSize );
if ( lpv == NULL )
return FALSE;
}
else
{
IMM32_HeapFree( lpMoveable->lpvMem );
lpv = NULL;
}
lpMoveable->dwSize = dwHeapSize;
lpMoveable->lpvMem = lpv;
return TRUE;
}
LPVOID IMM32_MoveableLock( IMM32_MOVEABLEMEM* lpMoveable )
{
if ( lpMoveable->dwLockCount == IMM32_MOVEABLEMEM_LOCK_MAX )
{
ERR( "lock count is 0xffffffff\n" );
}
else
{
lpMoveable->dwLockCount ++;
}
return lpMoveable->lpvMem;
}
BOOL IMM32_MoveableUnlock( IMM32_MOVEABLEMEM* lpMoveable )
{
if ( lpMoveable->dwLockCount == 0 )
return FALSE;
if ( --lpMoveable->dwLockCount > 0 )
return TRUE;
return FALSE;
}
DWORD IMM32_MoveableGetLockCount( IMM32_MOVEABLEMEM* lpMoveable )
{
return lpMoveable->dwLockCount;
}
DWORD IMM32_MoveableGetSize( IMM32_MOVEABLEMEM* lpMoveable )
{
return lpMoveable->dwSize;
}
/***********************************************************************
* ImmCreateIMCC (IMM32.@)
*
* Create IMCC(IMC Component).
*/
HIMCC WINAPI ImmCreateIMCC(DWORD dwSize)
{
IMM32_MOVEABLEMEM* lpMoveable;
TRACE("(%lu)\n", dwSize);
lpMoveable = IMM32_MoveableAlloc( HEAP_ZERO_MEMORY, dwSize );
if ( lpMoveable == NULL )
{
SetLastError(ERROR_OUTOFMEMORY);
return (HIMCC)NULL;
}
return (HIMCC)lpMoveable;
}
/***********************************************************************
* ImmDestroyIMCC (IMM32.@)
*
* Destroy IMCC(IMC Component).
*/
HIMCC WINAPI ImmDestroyIMCC(HIMCC hIMCC)
{
TRACE("(0x%08x)\n", (unsigned)hIMCC);
IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMCC );
return (HIMCC)NULL;
}
/***********************************************************************
* ImmLockIMCC (IMM32.@)
*/
LPVOID WINAPI ImmLockIMCC(HIMCC hIMCC)
{
TRACE("(0x%08x)\n", (unsigned)hIMCC);
return IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMCC );
}
/***********************************************************************
* ImmUnlockIMCC (IMM32.@)
*/
BOOL WINAPI ImmUnlockIMCC(HIMCC hIMCC)
{
TRACE("(0x%08x)\n", (unsigned)hIMCC);
return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMCC );
}
/***********************************************************************
* ImmGetIMCCLockCount (IMM32.@)
*/
DWORD WINAPI ImmGetIMCCLockCount(HIMCC hIMCC)
{
TRACE("(0x%08x)\n", (unsigned)hIMCC);
return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMCC );
}
/***********************************************************************
* ImmReSizeIMCC (IMM32.@)
*/
HIMCC WINAPI ImmReSizeIMCC(HIMCC hIMCC, DWORD dwSize)
{
TRACE("(0x%08x,%lu)\n", (unsigned)hIMCC, dwSize);
if ( !IMM32_MoveableReAlloc( (IMM32_MOVEABLEMEM*)hIMCC,
HEAP_ZERO_MEMORY, dwSize ) )
{
SetLastError(ERROR_OUTOFMEMORY);
return (HIMCC)NULL;
}
return hIMCC;
}
/***********************************************************************
* ImmGetIMCCSize (IMM32.@)
*/
DWORD WINAPI ImmGetIMCCSize(HIMCC hIMCC)
{
TRACE("(0x%08x)\n", (unsigned)hIMCC);
return IMM32_MoveableGetSize( (IMM32_MOVEABLEMEM*)hIMCC );
}
/*
* Helper functions for ANSI<->UNICODE string conversion
*
* Copyright 2000 Hidenori Takeshima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "immddk.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
#include "imm_private.h"
INT IMM32_strlenAtoW( LPCSTR lpstr )
{
INT len;
len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, NULL, 0 );
return ( len > 0 ) ? (len-1) : 0;
}
INT IMM32_strlenWtoA( LPCWSTR lpwstr )
{
INT len;
len = WideCharToMultiByte( CP_ACP, 0, lpwstr, -1,
NULL, 0, NULL, NULL );
return ( len > 0 ) ? (len-1) : 0;
}
LPWSTR IMM32_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen )
{
INT len;
len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, lpwstr, wbuflen );
if ( len == 0 )
*lpwstr = 0;
return lpwstr;
}
LPSTR IMM32_strncpyWtoA( LPSTR lpstr, LPCWSTR lpwstr, INT abuflen )
{
INT len;
len = WideCharToMultiByte( CP_ACP, 0, lpwstr, -1,
lpstr, abuflen, NULL, NULL );
if ( len == 0 )
*lpstr = 0;
return lpstr;
}
LPWSTR IMM32_strdupAtoW( LPCSTR lpstr )
{
INT len;
LPWSTR lpwstr = NULL;
len = IMM32_strlenAtoW( lpstr );
if ( len > 0 )
{
lpwstr = (LPWSTR)IMM32_HeapAlloc( 0, sizeof(WCHAR)*(len+1) );
if ( lpwstr != NULL )
(void)IMM32_strncpyAtoW( lpwstr, lpstr, len+1 );
}
return lpwstr;
}
LPSTR IMM32_strdupWtoA( LPCWSTR lpwstr )
{
INT len;
LPSTR lpstr = NULL;
len = IMM32_strlenWtoA( lpwstr );
if ( len > 0 )
{
lpstr = (LPSTR)IMM32_HeapAlloc( 0, sizeof(CHAR)*(len+1) );
if ( lpstr != NULL )
(void)IMM32_strncpyWtoA( lpstr, lpwstr, len+1 );
}
return lpstr;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment