4 * Copyright 2000 Hidenori Takeshima
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(imm);
33 #include "imm_private.h"
35 static HIMC IMM32_CreateIMC( HKL hkl );
36 static BOOL IMM32_DestroyIMC( HIMC hIMC );
38 IMM32_IMC* IMM32_LockIMC( HIMC hIMC )
42 if ( hIMC == NULLIMC )
44 SetLastError( ERROR_INVALID_HANDLE );
48 pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
49 if ( !pIMC->fSelected )
51 (void)IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
52 SetLastError( ERROR_ACCESS_DENIED );
59 BOOL IMM32_UnlockIMC( HIMC hIMC )
61 if ( hIMC == NULLIMC )
63 SetLastError( ERROR_INVALID_HANDLE );
67 return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
70 static HIMC IMM32_CreateIMC( HKL hkl )
72 IMM32_MOVEABLEMEM* hIMC;
74 LPCOMPOSITIONSTRING lpCompStr;
75 LPCANDIDATEINFO lpCandInfo;
76 LPGUIDELINE lpGuideLine;
78 hIMC = IMM32_MoveableAlloc( 0, sizeof( IMM32_IMC ) );
81 SetLastError( ERROR_OUTOFMEMORY );
85 pIMC = (IMM32_IMC*)IMM32_MoveableLock( hIMC );
87 /* Initialize some members of IMC. */
88 pIMC->context.hWnd = (HWND)NULL;
89 pIMC->context.fOpen = FALSE;
90 pIMC->context.hCompStr = (HIMCC)NULL;
91 pIMC->context.hCandInfo = (HIMCC)NULL;
92 pIMC->context.hGuideLine = (HIMCC)NULL;
93 pIMC->context.hPrivate = (HIMCC)NULL;
94 pIMC->context.dwNumMsgBuf = 0;
95 pIMC->context.hMsgBuf = (HIMCC)NULL;
96 pIMC->context.fdwInit = 0;
98 pIMC->fSelected = FALSE;
100 /* hCompStr, hCandInfo, hGuideLine, hMsgBuf must be allocated. */
101 pIMC->context.hCompStr = ImmCreateIMCC( sizeof(COMPOSITIONSTRING) );
102 if ( pIMC->context.hCompStr == (HIMCC)NULL )
104 lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC( pIMC->context.hCompStr );
105 if ( lpCompStr == NULL )
107 lpCompStr->dwSize = sizeof(COMPOSITIONSTRING);
108 (void)ImmUnlockIMCC( pIMC->context.hCompStr );
110 pIMC->context.hCandInfo = ImmCreateIMCC( sizeof(CANDIDATEINFO) );
111 if ( pIMC->context.hCandInfo == (HIMCC)NULL )
113 lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC( pIMC->context.hCandInfo );
114 if ( lpCandInfo == NULL )
116 lpCandInfo->dwSize = sizeof(CANDIDATEINFO);
117 (void)ImmUnlockIMCC( pIMC->context.hCandInfo );
119 pIMC->context.hGuideLine = ImmCreateIMCC( sizeof(GUIDELINE) );
120 if ( pIMC->context.hGuideLine == (HIMCC)NULL )
122 lpGuideLine = (LPGUIDELINE)ImmLockIMCC( pIMC->context.hGuideLine );
123 if ( lpGuideLine == NULL )
125 lpGuideLine->dwSize = sizeof(GUIDELINE);
126 (void)ImmUnlockIMCC( pIMC->context.hGuideLine );
128 pIMC->context.hMsgBuf = ImmCreateIMCC( 0 );
129 if ( pIMC->context.hMsgBuf == (HIMCC)NULL )
132 pIMC->pkl = IMM32_GetIME( hkl );
133 if ( pIMC->pkl != NULL )
135 /* The current HKL is IME.
136 * Initialize IME's private context.
138 if ( pIMC->pkl->imeinfo.dwPrivateDataSize > 0 )
140 pIMC->context.hPrivate = ImmCreateIMCC(
141 pIMC->pkl->imeinfo.dwPrivateDataSize );
142 if ( pIMC->context.hPrivate == (HIMCC)NULL )
146 pIMC->fSelected = TRUE;
147 if ( !pIMC->pkl->handlers.pImeSelect( (HIMC)hIMC, TRUE ) )
149 pIMC->fSelected = FALSE;
154 (void)IMM32_MoveableUnlock( hIMC );
159 (void)IMM32_DestroyIMC( (HIMC)hIMC );
160 SetLastError( ERROR_OUTOFMEMORY );
164 static BOOL IMM32_DestroyIMC( HIMC hIMC )
168 if ( hIMC == NULLIMC )
170 SetLastError( ERROR_INVALID_HANDLE );
174 pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
176 if ( pIMC->context.hWnd != (HWND)NULL )
178 FIXME( "please release lock of the context.hWnd!\n" );
181 if ( pIMC->fSelected )
183 (void)pIMC->pkl->handlers.pImeSelect( hIMC, FALSE );
184 pIMC->fSelected = FALSE;
187 if ( pIMC->context.hCompStr != (HIMCC)NULL )
188 (void)ImmDestroyIMCC(pIMC->context.hCompStr);
189 if ( pIMC->context.hCandInfo != (HIMCC)NULL )
190 (void)ImmDestroyIMCC(pIMC->context.hCandInfo);
191 if ( pIMC->context.hGuideLine != (HIMCC)NULL )
192 (void)ImmDestroyIMCC(pIMC->context.hGuideLine);
193 if ( pIMC->context.hPrivate != (HIMCC)NULL )
194 (void)ImmDestroyIMCC(pIMC->context.hPrivate);
195 if ( pIMC->context.hMsgBuf != (HIMCC)NULL )
196 (void)ImmDestroyIMCC(pIMC->context.hMsgBuf);
198 IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMC );
207 /***********************************************************************
208 * ImmCreateContext (IMM32.@)
210 HIMC WINAPI ImmCreateContext( void )
214 return IMM32_CreateIMC( GetKeyboardLayout(0) );
217 /***********************************************************************
218 * ImmDestroyContext (IMM32.@)
220 BOOL WINAPI ImmDestroyContext( HIMC hIMC )
222 TRACE("(0x%08x)\n",hIMC);
224 return IMM32_DestroyIMC( hIMC );
227 /***********************************************************************
228 * ImmLockIMC (IMM32.@)
230 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
234 TRACE("(0x%08x)\n", (unsigned)hIMC);
236 pIMC = IMM32_LockIMC( hIMC );
239 return &(pIMC->context);
242 /***********************************************************************
243 * ImmUnlockIMC (IMM32.@)
245 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
247 TRACE("(0x%08x)\n", (unsigned)hIMC);
249 return IMM32_UnlockIMC( hIMC );
252 /***********************************************************************
253 * ImmGetIMCLockCount (IMM32.@)
255 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
257 TRACE("(0x%08x)\n", (unsigned)hIMC);
259 if ( hIMC == NULLIMC )
261 SetLastError( ERROR_INVALID_HANDLE );
265 return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMC );