/*
 *	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 );
}
