| /* | |
| * The entry point of IMM32.DLL. | |
| * | |
| * Copyright 2000 Hidenori Takeshima | |
| */ | |
| #include "config.h" | |
| #include "winbase.h" | |
| #include "windef.h" | |
| #include "wingdi.h" | |
| #include "winuser.h" | |
| #include "winerror.h" | |
| #include "immddk.h" | |
| #include "debugtools.h" | |
| DEFAULT_DEBUG_CHANNEL(imm); | |
| #include "imm_private.h" | |
| static HANDLE IMM32_hHeap; | |
| static DWORD IMM32_dwTLSIndex; | |
| static CRITICAL_SECTION IMM32_csIMM; | |
| static BOOL IMM32_InitProcessMem( void ); | |
| static void IMM32_CleanupProcessMem( void ); | |
| static void IMM32_InitThreadData( void ); | |
| static void IMM32_CleanupThreadData( void ); | |
| /*********************************************************************** | |
| * IMM32_DllMain | |
| */ | |
| BOOL WINAPI IMM32_DllMain( | |
| HINSTANCE hInstDLL, | |
| DWORD fdwReason, | |
| LPVOID lpvReserved ) | |
| { | |
| switch ( fdwReason ) | |
| { | |
| case DLL_PROCESS_ATTACH: | |
| IMM32_InitProcessMem(); | |
| IMM32_RegisterIMEWndClass( hInstDLL ); | |
| break; | |
| case DLL_PROCESS_DETACH: | |
| IMM32_UnloadAllIMEs(); | |
| IMM32_UnregisterIMEWndClass( hInstDLL ); | |
| IMM32_CleanupProcessMem(); | |
| break; | |
| case DLL_THREAD_ATTACH: | |
| IMM32_InitThreadData(); | |
| break; | |
| case DLL_THREAD_DETACH: | |
| IMM32_CleanupThreadData(); | |
| break; | |
| } | |
| return TRUE; | |
| } | |
| static BOOL IMM32_InitProcessMem( void ) | |
| { | |
| IMM32_hHeap = (HANDLE)NULL; | |
| IMM32_dwTLSIndex = (DWORD)0xffffffff; | |
| IMM32_hHeap = HeapCreate( 0, 0x10000, 0 ); | |
| if ( IMM32_hHeap == (HANDLE)NULL ) | |
| { | |
| ERR( "cannot allocate heap for IMM32.\n" ); | |
| return FALSE; | |
| } | |
| IMM32_dwTLSIndex = TlsAlloc(); | |
| if ( IMM32_dwTLSIndex == (DWORD)0xffffffff ) | |
| { | |
| ERR( "cannot allocate a TLS for IMM.\n" ); | |
| return FALSE; | |
| } | |
| InitializeCriticalSection( &IMM32_csIMM ); | |
| return TRUE; | |
| } | |
| static void IMM32_CleanupProcessMem( void ) | |
| { | |
| DeleteCriticalSection( &IMM32_csIMM ); | |
| if ( IMM32_dwTLSIndex != (DWORD)0xffffffff ) | |
| { | |
| TlsFree( IMM32_dwTLSIndex ); | |
| IMM32_dwTLSIndex = (DWORD)0xffffffff; | |
| } | |
| if ( IMM32_hHeap != (HANDLE)NULL ) | |
| { | |
| (void)HeapDestroy( IMM32_hHeap ); | |
| IMM32_hHeap = (HANDLE)NULL; | |
| } | |
| } | |
| LPVOID IMM32_HeapAlloc( DWORD dwFlags, DWORD dwSize ) | |
| { | |
| return HeapAlloc( IMM32_hHeap, dwFlags, dwSize ); | |
| } | |
| LPVOID IMM32_HeapReAlloc( DWORD dwFlags, LPVOID lpv, DWORD dwSize ) | |
| { | |
| return HeapReAlloc( IMM32_hHeap, dwFlags, lpv, dwSize ); | |
| } | |
| void IMM32_HeapFree( LPVOID lpv ) | |
| { | |
| if ( lpv != NULL ) | |
| HeapFree( IMM32_hHeap, 0, lpv ); | |
| } | |
| static void IMM32_InitThreadData( void ) | |
| { | |
| TlsSetValue( IMM32_dwTLSIndex, NULL ); | |
| } | |
| static void IMM32_CleanupThreadData( void ) | |
| { | |
| IMM32_THREADDATA* pData; | |
| pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex ); | |
| if ( pData != NULL ) | |
| { | |
| /* Destroy Thread-local Data. */ | |
| if ( pData->hwndIME != (HWND)NULL ) | |
| DestroyWindow( pData->hwndIME ); | |
| if ( pData->hIMC != NULLIMC ) | |
| ImmDestroyContext( pData->hIMC ); | |
| IMM32_HeapFree( pData ); | |
| TlsSetValue( IMM32_dwTLSIndex, NULL ); | |
| } | |
| } | |
| IMM32_THREADDATA* IMM32_GetThreadData( void ) | |
| { | |
| IMM32_THREADDATA* pData; | |
| pData = (IMM32_THREADDATA*)TlsGetValue( IMM32_dwTLSIndex ); | |
| if ( pData != NULL ) | |
| return pData; | |
| pData = (IMM32_THREADDATA*) | |
| IMM32_HeapAlloc( 0, sizeof(IMM32_THREADDATA) ); | |
| if ( pData == NULL ) | |
| return NULL; | |
| /* Initialize Thread-local Data. */ | |
| pData->hwndIME = (HWND)NULL; | |
| pData->hIMC = NULLIMC; | |
| TlsSetValue( IMM32_dwTLSIndex, pData ); | |
| return pData; | |
| } | |
| HIMC IMM32_GetDefaultContext( void ) | |
| { | |
| IMM32_THREADDATA* pData; | |
| pData = IMM32_GetThreadData(); | |
| if ( pData == NULL ) | |
| return NULLIMC; | |
| if ( pData->hIMC == NULLIMC ) | |
| pData->hIMC = ImmCreateContext(); | |
| return pData->hIMC; | |
| } | |
| HWND IMM32_GetDefaultIMEWnd( void ) | |
| { | |
| IMM32_THREADDATA* pData; | |
| pData = IMM32_GetThreadData(); | |
| if ( pData == NULL ) | |
| return NULLIMC; | |
| if ( pData->hwndIME == (HWND)NULL ) | |
| pData->hwndIME = IMM32_CreateDefaultIMEWnd(); | |
| return pData->hwndIME; | |
| } | |
| void IMM32_Lock( void ) | |
| { | |
| EnterCriticalSection( &IMM32_csIMM ); | |
| } | |
| void IMM32_Unlock( void ) | |
| { | |
| LeaveCriticalSection( &IMM32_csIMM ); | |
| } |