269 lines
6.5 KiB
C
269 lines
6.5 KiB
C
/*
|
|
* 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 );
|
|
}
|
|
|
|
|