| /* |
| * The entry point of IMM32.DLL. |
| * |
| * Copyright 2000 Hidenori Takeshima |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "config.h" |
| |
| #include "winbase.h" |
| #include "windef.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winerror.h" |
| #include "immddk.h" |
| |
| #include "wine/debug.h" |
| WINE_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 ); |
| } |