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