Fixed some issues found by winapi_check.
[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 DWORD                    IMM32_dwProcessAttached = 0;
22 static HANDLE                   IMM32_hHeap;
23 static DWORD                    IMM32_dwTLSIndex;
24 static CRITICAL_SECTION         IMM32_csIMM;
25
26 static BOOL IMM32_InitProcessMem( void );
27 static void IMM32_CleanupProcessMem( void );
28 static void IMM32_InitThreadData( void );
29 static void IMM32_CleanupThreadData( void );
30
31
32 /***********************************************************************
33  *              IMM32_DllMain
34  */
35 BOOL WINAPI IMM32_DllMain(
36         HINSTANCE hInstDLL,
37         DWORD fdwReason,
38         LPVOID lpvReserved )
39 {
40         switch ( fdwReason )
41         {
42         case DLL_PROCESS_ATTACH:
43                 if ( IMM32_dwProcessAttached > 0 )
44                 {
45                         ERR( "cannot attach to two or more processes.\n" );
46                         return FALSE;
47                 }
48                 IMM32_dwProcessAttached ++;
49
50                 IMM32_InitProcessMem();
51                 IMM32_RegisterIMEWndClass( hInstDLL );
52                 break;
53         case DLL_PROCESS_DETACH:
54                 /*IMM32_UnloadAllIMEs();*/
55                 IMM32_UnregisterIMEWndClass( hInstDLL );
56                 IMM32_CleanupProcessMem();
57
58                 IMM32_dwProcessAttached --;
59                 break;
60         case DLL_THREAD_ATTACH:
61                 IMM32_InitThreadData();
62                 break;
63         case DLL_THREAD_DETACH:
64                 IMM32_CleanupThreadData();
65                 break;
66         }
67
68         return TRUE;
69 }
70
71 static BOOL IMM32_InitProcessMem( void )
72 {
73         IMM32_hHeap = (HANDLE)NULL;
74         IMM32_dwTLSIndex = (DWORD)0xffffffff;
75
76         IMM32_hHeap = HeapCreate( 0, 0x10000, 0 );
77         if ( IMM32_hHeap == (HANDLE)NULL )
78         {
79                 ERR( "cannot allocate heap for IMM32.\n" );
80                 return FALSE;
81         }
82
83         IMM32_dwTLSIndex = TlsAlloc();
84         if ( IMM32_dwTLSIndex == (DWORD)0xffffffff )
85         {
86                 ERR( "cannot allocate a TLS for IMM.\n" );
87                 return FALSE;
88         }
89
90         InitializeCriticalSection( &IMM32_csIMM );
91
92         return TRUE;
93 }
94
95 static void IMM32_CleanupProcessMem( void )
96 {
97         DeleteCriticalSection( &IMM32_csIMM );
98
99         if ( IMM32_dwTLSIndex != (DWORD)0xffffffff )
100         {
101                 TlsFree( IMM32_dwTLSIndex );
102                 IMM32_dwTLSIndex = (DWORD)0xffffffff;
103         }
104
105         if ( IMM32_hHeap != (HANDLE)NULL )
106         {
107                 (void)HeapDestroy( IMM32_hHeap );
108                 IMM32_hHeap = (HANDLE)NULL;
109         }
110 }
111
112 LPVOID IMM32_HeapAlloc( DWORD dwFlags, DWORD dwSize )
113 {
114         return HeapAlloc( IMM32_hHeap, dwFlags, dwSize );
115 }
116
117 LPVOID IMM32_HeapReAlloc( DWORD dwFlags, LPVOID lpv, DWORD dwSize )
118 {
119         return HeapReAlloc( IMM32_hHeap, dwFlags, lpv, dwSize );
120 }
121
122 void IMM32_HeapFree( LPVOID lpv )
123 {
124         if ( lpv != NULL )
125                 HeapFree( IMM32_hHeap, 0, lpv );
126 }
127
128
129 static void IMM32_InitThreadData( void )
130 {
131         TlsSetValue( IMM32_dwTLSIndex, NULL );
132 }
133
134 static void IMM32_CleanupThreadData( void )
135 {
136         IMM32_THREADDATA*       pData;
137
138         pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
139         if ( pData != NULL )
140         {
141                 /* Destroy Thread-local Data. */
142                 if ( pData->hwndIME != (HWND)NULL )
143                         DestroyWindow( pData->hwndIME );
144                 if ( pData->hIMC != NULLIMC )
145                         ImmDestroyContext( pData->hIMC );
146
147                 IMM32_HeapFree( pData );
148                 TlsSetValue( IMM32_dwTLSIndex, NULL );
149         }
150 }
151
152 IMM32_THREADDATA* IMM32_GetThreadData( void )
153 {
154         IMM32_THREADDATA*       pData;
155
156         pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex );
157         if ( pData != NULL )
158                 return pData;
159
160         pData = (IMM32_THREADDATA*)
161                         IMM32_HeapAlloc( 0, sizeof(IMM32_THREADDATA) );
162         if ( pData == NULL )
163                 return NULL;
164
165         /* Initialize Thread-local Data. */
166         pData->hwndIME = (HWND)NULL;
167         pData->hIMC = NULLIMC;
168
169         TlsSetValue( IMM32_dwTLSIndex, pData );
170
171         return pData;
172 }
173