Added a framework for testing CreateProcess and a few tests.
[wine] / dlls / imm32 / imc.c
1 /*
2  *      Input Method Context
3  *
4  *      Copyright 2000 Hidenori Takeshima
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include "winbase.h"
24 #include "windef.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winerror.h"
28 #include "immddk.h"
29
30 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(imm);
32
33 #include "imm_private.h"
34
35 static HIMC IMM32_CreateIMC( HKL hkl );
36 static BOOL IMM32_DestroyIMC( HIMC hIMC );
37
38 IMM32_IMC* IMM32_LockIMC( HIMC hIMC )
39 {
40         IMM32_IMC*      pIMC;
41
42         if ( hIMC == NULLIMC )
43         {
44                 SetLastError( ERROR_INVALID_HANDLE );
45                 return NULL;
46         }
47
48         pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
49         if ( !pIMC->fSelected )
50         {
51                 (void)IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
52                 SetLastError( ERROR_ACCESS_DENIED );
53                 return NULL;
54         }
55
56         return pIMC;
57 }
58
59 BOOL IMM32_UnlockIMC( HIMC hIMC )
60 {
61         if ( hIMC == NULLIMC )
62         {
63                 SetLastError( ERROR_INVALID_HANDLE );
64                 return FALSE;
65         }
66
67         return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
68 }
69
70 static HIMC IMM32_CreateIMC( HKL hkl )
71 {
72         IMM32_MOVEABLEMEM*      hIMC;
73         IMM32_IMC*              pIMC;
74         LPCOMPOSITIONSTRING     lpCompStr;
75         LPCANDIDATEINFO         lpCandInfo;
76         LPGUIDELINE             lpGuideLine;
77
78         hIMC = IMM32_MoveableAlloc( 0, sizeof( IMM32_IMC ) );
79         if ( hIMC == NULL )
80         {
81                 SetLastError( ERROR_OUTOFMEMORY );
82                 return NULLIMC;
83         }
84
85         pIMC = (IMM32_IMC*)IMM32_MoveableLock( hIMC );
86
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;
97         pIMC->pkl = NULL;
98         pIMC->fSelected = FALSE;
99
100         /* hCompStr, hCandInfo, hGuideLine, hMsgBuf must be allocated. */
101         pIMC->context.hCompStr = ImmCreateIMCC( sizeof(COMPOSITIONSTRING) );
102         if ( pIMC->context.hCompStr == (HIMCC)NULL )
103                 goto out_of_memory;
104         lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC( pIMC->context.hCompStr );
105         if ( lpCompStr == NULL )
106                 goto out_of_memory;
107         lpCompStr->dwSize = sizeof(COMPOSITIONSTRING);
108         (void)ImmUnlockIMCC( pIMC->context.hCompStr );
109
110         pIMC->context.hCandInfo = ImmCreateIMCC( sizeof(CANDIDATEINFO) );
111         if ( pIMC->context.hCandInfo == (HIMCC)NULL )
112                 goto out_of_memory;
113         lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC( pIMC->context.hCandInfo );
114         if ( lpCandInfo == NULL )
115                 goto out_of_memory;
116         lpCandInfo->dwSize = sizeof(CANDIDATEINFO);
117         (void)ImmUnlockIMCC( pIMC->context.hCandInfo );
118
119         pIMC->context.hGuideLine = ImmCreateIMCC( sizeof(GUIDELINE) );
120         if ( pIMC->context.hGuideLine == (HIMCC)NULL )
121                 goto out_of_memory;
122         lpGuideLine = (LPGUIDELINE)ImmLockIMCC( pIMC->context.hGuideLine );
123         if ( lpGuideLine == NULL )
124                 goto out_of_memory;
125         lpGuideLine->dwSize = sizeof(GUIDELINE);
126         (void)ImmUnlockIMCC( pIMC->context.hGuideLine );
127
128         pIMC->context.hMsgBuf = ImmCreateIMCC( 0 );
129         if ( pIMC->context.hMsgBuf == (HIMCC)NULL )
130                 goto out_of_memory;
131
132         pIMC->pkl = IMM32_GetIME( hkl );
133         if ( pIMC->pkl != NULL )
134         {
135                 /* The current HKL is IME.
136                  * Initialize IME's private context.
137                  */
138                 if ( pIMC->pkl->imeinfo.dwPrivateDataSize > 0 )
139                 {
140                         pIMC->context.hPrivate = ImmCreateIMCC(
141                                 pIMC->pkl->imeinfo.dwPrivateDataSize );
142                         if ( pIMC->context.hPrivate == (HIMCC)NULL )
143                                 goto out_of_memory;
144                 }
145
146                 pIMC->fSelected = TRUE;
147                 if ( !pIMC->pkl->handlers.pImeSelect( (HIMC)hIMC, TRUE ) )
148                 {
149                         pIMC->fSelected = FALSE;
150                         goto out_of_memory;
151                 }
152         }
153
154         (void)IMM32_MoveableUnlock( hIMC );
155
156         return (HIMC)hIMC;
157
158 out_of_memory:
159         (void)IMM32_DestroyIMC( (HIMC)hIMC );
160         SetLastError( ERROR_OUTOFMEMORY );
161         return NULLIMC;
162 }
163
164 static BOOL IMM32_DestroyIMC( HIMC hIMC )
165 {
166         IMM32_IMC*              pIMC;
167
168         if ( hIMC == NULLIMC )
169         {
170                 SetLastError( ERROR_INVALID_HANDLE );
171                 return FALSE;
172         }
173
174         pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
175
176         if ( pIMC->context.hWnd != (HWND)NULL )
177         {
178                 FIXME( "please release lock of the context.hWnd!\n" );
179         }
180
181         if ( pIMC->fSelected )
182         {
183                 (void)pIMC->pkl->handlers.pImeSelect( hIMC, FALSE );
184                 pIMC->fSelected = FALSE;
185         }
186
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);
197
198         IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMC );
199
200         return TRUE;
201 }
202
203
204
205
206
207 /***********************************************************************
208  *              ImmCreateContext (IMM32.@)
209  */
210 HIMC WINAPI ImmCreateContext( void )
211 {
212         TRACE("()\n");
213
214         return IMM32_CreateIMC( GetKeyboardLayout(0) );
215 }
216
217 /***********************************************************************
218  *              ImmDestroyContext (IMM32.@)
219  */
220 BOOL WINAPI ImmDestroyContext( HIMC hIMC )
221 {
222         TRACE("(0x%08x)\n",hIMC);
223
224         return IMM32_DestroyIMC( hIMC );
225 }
226
227 /***********************************************************************
228  *              ImmLockIMC (IMM32.@)
229  */
230 LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
231 {
232         IMM32_IMC*      pIMC;
233
234         TRACE("(0x%08x)\n", (unsigned)hIMC);
235
236         pIMC = IMM32_LockIMC( hIMC );
237         if ( pIMC == NULL )
238                 return NULL;
239         return &(pIMC->context);
240 }
241
242 /***********************************************************************
243  *              ImmUnlockIMC (IMM32.@)
244  */
245 BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
246 {
247         TRACE("(0x%08x)\n", (unsigned)hIMC);
248
249         return IMM32_UnlockIMC( hIMC );
250 }
251
252 /***********************************************************************
253  *              ImmGetIMCLockCount (IMM32.@)
254  */
255 DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
256 {
257         TRACE("(0x%08x)\n", (unsigned)hIMC);
258
259         if ( hIMC == NULLIMC )
260         {
261                 SetLastError( ERROR_INVALID_HANDLE );
262                 return 0;
263         }
264
265         return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMC );
266 }
267
268