| /* |
| * 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 ); |
| } |
| |
| |