Added an unknown VxD error code.
[wine] / dlls / imm32 / main.c
1 /*
2  *      The entry point of IMM32.DLL.
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 HANDLE                   IMM32_hHeap;
22 static DWORD                    IMM32_dwTLSIndex;
23 static CRITICAL_SECTION         IMM32_csIMM;
24
25 static BOOL IMM32_InitProcessMem( void );
26 static void IMM32_CleanupProcessMem( void );
27 static void IMM32_InitThreadData( void );
28 static void IMM32_CleanupThreadData( void );
29
30
31 /***********************************************************************
32  *              IMM32_DllMain
33  */
34 BOOL WINAPI IMM32_DllMain(
35         HINSTANCE hInstDLL,
36         DWORD fdwReason,
37         LPVOID lpvReserved )
38 {
39         switch ( fdwReason )
40         {
41         case DLL_PROCESS_ATTACH:
42                 IMM32_InitProcessMem();
43                 IMM32_RegisterIMEWndClass( hInstDLL );
44                 break;
45         case DLL_PROCESS_DETACH:
46                 IMM32_UnloadAllIMEs();
47                 IMM32_UnregisterIMEWndClass( hInstDLL );
48                 IMM32_CleanupProcessMem();
49                 break;
50         case DLL_THREAD_ATTACH:
51                 IMM32_InitThreadData();
52                 break;
53         case DLL_THREAD_DETACH:
54                 IMM32_CleanupThreadData();
55                 break;
56         }
57
58         return TRUE;
59 }
60
61 static BOOL IMM32_InitProcessMem( void )
62 {
63         IMM32_hHeap = (HANDLE)NULL;
64         IMM32_dwTLSIndex = (DWORD)0xffffffff;
65
66         IMM32_hHeap = HeapCreate( 0, 0x10000, 0 );
67         if ( IMM32_hHeap == (HANDLE)NULL )
68         {
69                 ERR( "cannot allocate heap for IMM32.\n" );
70                 return FALSE;
71         }
72
73         IMM32_dwTLSIndex = TlsAlloc();
74         if ( IMM32_dwTLSIndex == (DWORD)0xffffffff )
75         {
76                 ERR( "cannot allocate a TLS for IMM.\n" );
77                 return FALSE;
78         }
79
80         InitializeCriticalSection( &IMM32_csIMM );
81
82         return TRUE;
83 }
84
85 static void IMM32_CleanupProcessMem( void )
86 {
87         DeleteCriticalSection( &IMM32_csIMM );
88
89         if ( IMM32_dwTLSIndex != (DWORD)0xffffffff )
90         {
91                 TlsFree( IMM32_dwTLSIndex );
92                 IMM32_dwTLSIndex = (DWORD)0xffffffff;
93         }
94
95         if ( IMM32_hHeap != (HANDLE)NULL )
96         {
97                 (void)HeapDestroy( IMM32_hHeap );
98                 IMM32_hHeap = (HANDLE)NULL;
99         }
100 }
101
102 LPVOID IMM32_HeapAlloc( DWORD dwFlags, DWORD dwSize )
103 {
104         return HeapAlloc( IMM32_hHeap, dwFlags, dwSize );
105 }
106
107 LPVOID IMM32_HeapReAlloc( DWORD dwFlags, LPVOID lpv, DWORD dwSize )
108 {
109         return HeapReAlloc( IMM32_hHeap, dwFlags, lpv, dwSize );
110 }
111
112 void IMM32_HeapFree( LPVOID lpv )
113 {
114         if ( lpv != NULL )
115                 HeapFree( IMM32_hHeap, 0, lpv );
116 }
117
118
119 static void IMM32_InitThreadData( void )
120 {
121         TlsSetValue( IMM32_dwTLSIndex, NULL );
122 }
123
124 static void IMM32_CleanupThreadData( void )
125 {
126         IMM32_THREADDATA*       pData;
127
128         pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
129         if ( pData != NULL )
130         {
131                 /* Destroy Thread-local Data. */
132                 if ( pData->hwndIME != (HWND)NULL )
133                         DestroyWindow( pData->hwndIME );
134                 if ( pData->hIMC != NULLIMC )
135                         ImmDestroyContext( pData->hIMC );
136
137                 IMM32_HeapFree( pData );
138                 TlsSetValue( IMM32_dwTLSIndex, NULL );
139         }
140 }
141
142 IMM32_THREADDATA* IMM32_GetThreadData( void )
143 {
144         IMM32_THREADDATA*       pData;
145
146         pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
147         if ( pData != NULL )
148                 return pData;
149
150         pData = (IMM32_THREADDATA*)
151                         IMM32_HeapAlloc( 0, sizeof(IMM32_THREADDATA) );
152         if ( pData == NULL )
153                 return NULL;
154
155         /* Initialize Thread-local Data. */
156         pData->hwndIME = (HWND)NULL;
157         pData->hIMC = NULLIMC;
158
159         TlsSetValue( IMM32_dwTLSIndex, pData );
160
161         return pData;
162 }
163
164 HIMC IMM32_GetDefaultContext( void )
165 {
166         IMM32_THREADDATA*       pData;
167
168         pData = IMM32_GetThreadData();
169         if ( pData == NULL )
170                 return NULLIMC;
171         if ( pData->hIMC == NULLIMC )
172                 pData->hIMC = ImmCreateContext();
173
174         return pData->hIMC;
175 }
176
177 HWND IMM32_GetDefaultIMEWnd( void )
178 {
179         IMM32_THREADDATA*       pData;
180
181         pData = IMM32_GetThreadData();
182         if ( pData == NULL )
183                 return NULLIMC;
184         if ( pData->hwndIME == (HWND)NULL )
185                 pData->hwndIME = IMM32_CreateDefaultIMEWnd();
186
187         return pData->hwndIME;
188 }
189
190
191 void IMM32_Lock( void )
192 {
193         EnterCriticalSection( &IMM32_csIMM );
194 }
195
196 void IMM32_Unlock( void )
197 {
198         LeaveCriticalSection( &IMM32_csIMM );
199 }