214 lines
4.5 KiB
C
214 lines
4.5 KiB
C
/*
|
|
* 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 );
|
|
}
|