Set an overlapped hEvent before calling any APCs.
[wine] / dlls / imm32 / memory.c
1 /*
2  *      This file implements 'moveable' memory block.
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 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(imm);
31
32 #include "imm_private.h"
33
34 #define IMM32_MOVEABLEMEM_LOCK_MAX      ((DWORD)0xffffffff)
35
36 struct IMM32_tagMOVEABLEMEM
37 {
38         DWORD                           dwLockCount;
39         DWORD                           dwSize;
40         LPVOID                          lpvMem;
41 };
42
43 IMM32_MOVEABLEMEM* IMM32_MoveableAlloc( DWORD dwHeapFlags, DWORD dwHeapSize )
44 {
45         IMM32_MOVEABLEMEM*      lpMoveable;
46
47         lpMoveable = (IMM32_MOVEABLEMEM*)
48                 IMM32_HeapAlloc( 0, sizeof( IMM32_MOVEABLEMEM ) );
49         if ( lpMoveable != NULL )
50         {
51                 lpMoveable->dwLockCount = 0;
52                 lpMoveable->dwSize = dwHeapSize;
53                 lpMoveable->lpvMem = NULL;
54
55                 if ( dwHeapSize > 0 )
56                 {
57                         lpMoveable->lpvMem =
58                                 IMM32_HeapAlloc( dwHeapFlags, dwHeapSize );
59                         if ( lpMoveable->lpvMem == NULL )
60                         {
61                                 IMM32_HeapFree( lpMoveable );
62                                 lpMoveable = NULL;
63                         }
64                 }
65         }
66
67         return lpMoveable;
68 }
69
70 void IMM32_MoveableFree( IMM32_MOVEABLEMEM* lpMoveable )
71 {
72         IMM32_HeapFree( lpMoveable->lpvMem );
73         IMM32_HeapFree( lpMoveable );
74 }
75
76 BOOL IMM32_MoveableReAlloc( IMM32_MOVEABLEMEM* lpMoveable,
77                             DWORD dwHeapFlags, DWORD dwHeapSize )
78 {
79         LPVOID  lpv;
80
81         if ( dwHeapSize > 0 )
82         {
83                 if ( lpMoveable->dwLockCount > 0 )
84                         dwHeapFlags |= HEAP_REALLOC_IN_PLACE_ONLY;
85                 lpv = IMM32_HeapReAlloc( dwHeapFlags,
86                                          lpMoveable->lpvMem, dwHeapSize );
87                 if ( lpv == NULL )
88                         return FALSE;
89         }
90         else
91         {
92                 IMM32_HeapFree( lpMoveable->lpvMem );
93                 lpv = NULL;
94         }
95
96         lpMoveable->dwSize = dwHeapSize;
97         lpMoveable->lpvMem = lpv;
98
99         return TRUE;
100 }
101
102 LPVOID IMM32_MoveableLock( IMM32_MOVEABLEMEM* lpMoveable )
103 {
104         if ( lpMoveable->dwLockCount == IMM32_MOVEABLEMEM_LOCK_MAX )
105         {
106                 ERR( "lock count is 0xffffffff\n" );
107         }
108         else
109         {
110                 lpMoveable->dwLockCount ++;
111         }
112
113         return lpMoveable->lpvMem;
114 }
115
116 BOOL IMM32_MoveableUnlock( IMM32_MOVEABLEMEM* lpMoveable )
117 {
118         if ( lpMoveable->dwLockCount == 0 )
119                 return FALSE;
120
121         if ( --lpMoveable->dwLockCount > 0 )
122                 return TRUE;
123
124         return FALSE;
125 }
126
127 DWORD IMM32_MoveableGetLockCount( IMM32_MOVEABLEMEM* lpMoveable )
128 {
129         return lpMoveable->dwLockCount;
130 }
131
132 DWORD IMM32_MoveableGetSize( IMM32_MOVEABLEMEM* lpMoveable )
133 {
134         return lpMoveable->dwSize;
135 }
136
137
138
139 /***********************************************************************
140  *              ImmCreateIMCC (IMM32.@)
141  *
142  * Create IMCC(IMC Component).
143  */
144 HIMCC WINAPI ImmCreateIMCC(DWORD dwSize)
145 {
146         IMM32_MOVEABLEMEM* lpMoveable;
147
148         TRACE("(%lu)\n", dwSize);
149
150         lpMoveable = IMM32_MoveableAlloc( HEAP_ZERO_MEMORY, dwSize );
151         if ( lpMoveable == NULL )
152         {
153                 SetLastError(ERROR_OUTOFMEMORY);
154                 return (HIMCC)NULL;
155         }
156
157         return (HIMCC)lpMoveable;
158 }
159
160 /***********************************************************************
161  *              ImmDestroyIMCC (IMM32.@)
162  *
163  * Destroy IMCC(IMC Component).
164  */
165 HIMCC WINAPI ImmDestroyIMCC(HIMCC hIMCC)
166 {
167         TRACE("(0x%08x)\n", (unsigned)hIMCC);
168
169         IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMCC );
170         return (HIMCC)NULL;
171 }
172
173 /***********************************************************************
174  *              ImmLockIMCC (IMM32.@)
175  */
176 LPVOID WINAPI ImmLockIMCC(HIMCC hIMCC)
177 {
178         TRACE("(0x%08x)\n", (unsigned)hIMCC);
179
180         return IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMCC );
181 }
182
183 /***********************************************************************
184  *              ImmUnlockIMCC (IMM32.@)
185  */
186 BOOL WINAPI ImmUnlockIMCC(HIMCC hIMCC)
187 {
188         TRACE("(0x%08x)\n", (unsigned)hIMCC);
189
190         return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMCC );
191 }
192
193 /***********************************************************************
194  *              ImmGetIMCCLockCount (IMM32.@)
195  */
196 DWORD WINAPI ImmGetIMCCLockCount(HIMCC hIMCC)
197 {
198         TRACE("(0x%08x)\n", (unsigned)hIMCC);
199
200         return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMCC );
201 }
202
203 /***********************************************************************
204  *              ImmReSizeIMCC (IMM32.@)
205  */
206 HIMCC WINAPI ImmReSizeIMCC(HIMCC hIMCC, DWORD dwSize)
207 {
208         TRACE("(0x%08x,%lu)\n", (unsigned)hIMCC, dwSize);
209
210         if ( !IMM32_MoveableReAlloc( (IMM32_MOVEABLEMEM*)hIMCC,
211                                      HEAP_ZERO_MEMORY, dwSize ) )
212         {
213                 SetLastError(ERROR_OUTOFMEMORY);
214                 return (HIMCC)NULL;
215         }
216
217         return hIMCC;
218 }
219
220 /***********************************************************************
221  *              ImmGetIMCCSize (IMM32.@)
222  */
223 DWORD WINAPI ImmGetIMCCSize(HIMCC hIMCC)
224 {
225         TRACE("(0x%08x)\n", (unsigned)hIMCC);
226
227         return IMM32_MoveableGetSize( (IMM32_MOVEABLEMEM*)hIMCC );
228 }
229
230