/**
 * Copyright (C) 2009 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Mobile Communication Division,
 * Digital Media & Communications Business, Samsung Electronics Co., Ltd.
 *
 * This software and its documentation are confidential and proprietary
 * information of Samsung Electronics Co., Ltd.  No part of the software and
 * documents may be copied, reproduced, transmitted, translated, or reduced to
 * any electronic medium or machine-readable form without the prior written
 * consent of Samsung Electronics.
 *
 * Samsung Electronics makes no representations with respect to the contents,
 * and assumes no responsibility for any errors that might appear in the
 * software and documents. This publication and the contents hereof are subject
 * to change without notice.
 */

#include "et9kdbUtil.h"
#include "et9imuUtil.h"
#ifndef LOAD_DB_FROM_FILE
#include "gen_option.h"
#endif
#include "et9misc.h"
#ifdef ET9_KDB_MODULE
/*----------------------------------------------------------------------------
 * External Variables
 *----------------------------------------------------------------------------*/
#ifndef LOAD_DB_FROM_FILE

#if defined(_FEATURE_SUPPORT_LANG_AZERBAIJANI_) 
extern const ET9U8 ET9FARDATA l0671b00[];
extern const ET9U8 ET9FARDATA l0971b00[];
extern const ET9U8 ET9FARDATA l0971b01[];
extern const ET9U8 ET9FARDATA l0971b02[];
#endif

#if defined(_FEATURE_SUPPORT_LANG_ARMENIAN_) 
extern const ET9U8 ET9FARDATA l0690b00[];
extern const ET9U8 ET9FARDATA l0990b00[];
extern const ET9U8 ET9FARDATA l0990b01[];
extern const ET9U8 ET9FARDATA l0990b02[];
extern const ET9U8 ET9FARDATA l0990b03[];
#endif

#if defined(_FEATURE_SUPPORT_LANG_GEORGIAN_) 
extern const ET9U8 ET9FARDATA l0696b00[];
extern const ET9U8 ET9FARDATA l0996b00[];
extern const ET9U8 ET9FARDATA l0996b01[];
extern const ET9U8 ET9FARDATA l0996b02[];
#endif

///////////////////////////////////////////
#if defined(_FEATURE_SUPPORT_LANG_FARSI_) 
extern const ET9U8 ET9FARDATA l0641b00[];
extern const ET9U8 ET9FARDATA l0841b00[];
#endif
////////////////////////////////////////////
#if defined(_FEATURE_SUPPORT_LANG_ARABIC_) 
extern const ET9U8 ET9FARDATA l0601b00[];
extern const ET9U8 ET9FARDATA l0801b00[];
#endif
#if defined(_FEATURE_SUPPORT_LANG_URDU_) 
extern const ET9U8 ET9FARDATA l0632b00[];
extern const ET9U8 ET9FARDATA l0832b00[];
#endif
#if defined(_FEATURE_SUPPORT_LANG_HEBREW_)
extern const ET9U8 ET9FARDATA l0613b00[];
extern const ET9U8 ET9FARDATA l0813b00[];
#endif//_FEATURE_SUPPORT_LANG_HEBREW_
#if defined(_FEATURE_SUPPORT_LANG_BULGARIAN_)
extern const ET9U8 ET9FARDATA l0702b00[];
extern const ET9U8 ET9FARDATA l0602b00[];
#endif//_FEATURE_SUPPORT_LANG_BULGARIAN_
#if defined(_FEATURE_SUPPORT_LANG_CROATIAN_)
extern const ET9U8 ET9FARDATA l0789b00[];
extern const ET9U8 ET9FARDATA l0589b00[];
extern const ET9U8 ET9FARDATA l0689b00[];
#endif//_FEATURE_SUPPORT_LANG_CROATIAN_
#if defined(_FEATURE_SUPPORT_LANG_CZECH_)
extern const ET9U8 ET9FARDATA l0705b00[];
extern const ET9U8 ET9FARDATA l0505b00[];
extern const ET9U8 ET9FARDATA l0605b00[];
#endif//_FEATURE_SUPPORT_LANG_CZECH_
#if defined(_FEATURE_SUPPORT_LANG_DANISH_)
extern const ET9U8 ET9FARDATA l0706b00[];
extern const ET9U8 ET9FARDATA l0506b00[];
extern const ET9U8 ET9FARDATA l0606b00[];
#endif//_FEATURE_SUPPORT_LANG_DANISH_
#if defined(_FEATURE_SUPPORT_LANG_DUTCH_)
extern const ET9U8 ET9FARDATA l0719b00[];
extern const ET9U8 ET9FARDATA l0519b00[];
extern const ET9U8 ET9FARDATA l0619b00[];
#endif//_FEATURE_SUPPORT_LANG_DUTCH_
#if defined(_FEATURE_SUPPORT_LANG_ENGLISH_)
extern const ET9U8 ET9FARDATA l0709b00[];
extern const ET9U8 ET9FARDATA l0509b00[];
extern const ET9U8 ET9FARDATA l0609b00[];
#endif//_FEATURE_SUPPORT_LANG_ENGLISH_
#if defined(_FEATURE_SUPPORT_LANG_FINNISH_)
extern const ET9U8 ET9FARDATA l0711b00[];
extern const ET9U8 ET9FARDATA l0511b00[];
extern const ET9U8 ET9FARDATA l0611b00[];
#endif//_FEATURE_SUPPORT_LANG_FINNISH_
#if defined(_FEATURE_SUPPORT_LANG_FRENCH_)
extern const ET9U8 ET9FARDATA l0712b00[];
extern const ET9U8 ET9FARDATA l0512b00[];
extern const ET9U8 ET9FARDATA l0612b00[];
#endif//_FEATURE_SUPPORT_LANG_FRENCH_
#if defined(_FEATURE_SUPPORT_LANG_GERMAN_)
extern const ET9U8 ET9FARDATA l0707b00[];
extern const ET9U8 ET9FARDATA l0507b00[];
extern const ET9U8 ET9FARDATA l0607b00[];
#endif//_FEATURE_SUPPORT_LANG_GERMAN_
#if defined(_FEATURE_SUPPORT_LANG_GREEK_)
extern const ET9U8 ET9FARDATA l0708b00[];
extern const ET9U8 ET9FARDATA l0508b00[];
extern const ET9U8 ET9FARDATA l0608b00[];
#endif//_FEATURE_SUPPORT_LANG_GREEK_
#if defined(_FEATURE_SUPPORT_LANG_HUNGARIAN_)
extern const ET9U8 ET9FARDATA l0714b00[];
extern const ET9U8 ET9FARDATA l0514b00[];
extern const ET9U8 ET9FARDATA l0614b00[];
#endif//_FEATURE_SUPPORT_LANG_HUNGARIAN_
#if defined(_FEATURE_SUPPORT_LANG_ITALIAN_)
extern const ET9U8 ET9FARDATA l0716b00[];
extern const ET9U8 ET9FARDATA l0516b00[];
extern const ET9U8 ET9FARDATA l0616b00[];
#endif//_FEATURE_SUPPORT_LANG_ITALIAN_
#if defined(_FEATURE_SUPPORT_LANG_NORWEGIAN_)
extern const ET9U8 ET9FARDATA l0720b00[];
extern const ET9U8 ET9FARDATA l0520b00[];
extern const ET9U8 ET9FARDATA l0620b00[];
#endif//_FEATURE_SUPPORT_LANG_NORWEGIAN_
#if defined(_FEATURE_SUPPORT_LANG_POLISH_)
extern const ET9U8 ET9FARDATA l0721b00[];
extern const ET9U8 ET9FARDATA l0521b00[];
extern const ET9U8 ET9FARDATA l0621b00[];
#endif//_FEATURE_SUPPORT_LANG_POLISH_
#if defined(_FEATURE_SUPPORT_LANG_PORTUGUESE_)
extern const ET9U8 ET9FARDATA l0722b00[];
extern const ET9U8 ET9FARDATA l0522b00[];
extern const ET9U8 ET9FARDATA l0622b00[];
#endif//_FEATURE_SUPPORT_LANG_PORTUGUESE_
#if defined(_FEATURE_SUPPORT_LANG_ROMANIAN_)
extern const ET9U8 ET9FARDATA l0724b00[];
extern const ET9U8 ET9FARDATA l0524b00[];
extern const ET9U8 ET9FARDATA l0624b00[];
#endif//_FEATURE_SUPPORT_LANG_ROMANIAN_
#if defined(_FEATURE_SUPPORT_LANG_RUSSIAN_)
extern const ET9U8 ET9FARDATA l0725b00[];
extern const ET9U8 ET9FARDATA l0525b00[];
extern const ET9U8 ET9FARDATA l0625b00[];
#endif//_FEATURE_SUPPORT_LANG_RUSSIAN_
#if defined(_FEATURE_SUPPORT_LANG_SPANISH_)
extern const ET9U8 ET9FARDATA l0710b00[];
extern const ET9U8 ET9FARDATA l0510b00[];
extern const ET9U8 ET9FARDATA l0610b00[];
#endif//_FEATURE_SUPPORT_LANG_SPANISH_
#if defined(_FEATURE_SUPPORT_LANG_SWEDISH_)
extern const ET9U8 ET9FARDATA l0729b00[];
extern const ET9U8 ET9FARDATA l0529b00[];
extern const ET9U8 ET9FARDATA l0629b00[];
#endif//_FEATURE_SUPPORT_LANG_SWEDISH_
#if defined(_FEATURE_SUPPORT_LANG_TURKISH_)
extern const ET9U8 ET9FARDATA l0731b00[];
extern const ET9U8 ET9FARDATA l0531b00[];
extern const ET9U8 ET9FARDATA l0631b00[];
#endif//_FEATURE_SUPPORT_LANG_TURKISH_
#if defined(_FEATURE_SUPPORT_LANG_KOREAN_)
extern const ET9U8 ET9FARDATA l0918b00[];
extern const ET9U8 ET9FARDATA l0618b00[];
#endif//_FEATURE_SUPPORT_LANG_KOREAN_
#if defined(_FEATURE_SUPPORT_LANG_SLOVAK_)
extern const ET9U8 ET9FARDATA l0727b00[];
extern const ET9U8 ET9FARDATA l0527b00[];
extern const ET9U8 ET9FARDATA l0627b00[];
#endif//_FEATURE_SUPPORT_LANG_SLOVAK_
#if defined(_FEATURE_SUPPORT_LANG_UKRAINIAN_)
extern const ET9U8 ET9FARDATA l0734b00[];
extern const ET9U8 ET9FARDATA l0534b00[];
extern const ET9U8 ET9FARDATA l0634b00[];
#endif//_FEATURE_SUPPORT_LANG_UKRAINIAN_
#if defined(_FEATURE_SUPPORT_LANG_ESTONIAN_)
extern const ET9U8 ET9FARDATA l0637b00[];
extern const ET9U8 ET9FARDATA l0737b00[];
#endif//_FEATURE_SUPPORT_LANG_ESTONIAN_
#if defined(_FEATURE_SUPPORT_LANG_LATVIAN_)
extern const ET9U8 ET9FARDATA l0638b00[];
extern const ET9U8 ET9FARDATA l0738b00[];
#endif//_FEATURE_SUPPORT_LANG_LATVIAN_
#if defined(_FEATURE_SUPPORT_LANG_LITHUANIAN_)
extern const ET9U8 ET9FARDATA l0639b00[];
extern const ET9U8 ET9FARDATA l0739b00[];
#endif//_FEATURE_SUPPORT_LANG_LITHUANIAN_
#if defined(_FEATURE_SUPPORT_LANG_SERBIAN_)
extern const ET9U8 ET9FARDATA l06128b00[];
extern const ET9U8 ET9FARDATA l07128b00[];
#endif//_FEATURE_SUPPORT_LANG_SERBIAN_
#if defined(_FEATURE_SUPPORT_LANG_KAZAKH_)
extern const ET9U8 ET9FARDATA l0697b00[];
extern const ET9U8 ET9FARDATA l0797b00[];
#endif//_FEATURE_SUPPORT_LANG_KAZAKH_
#if defined(_FEATURE_SUPPORT_LANG_SLOVENIAN_)
extern const ET9U8 ET9FARDATA l0636b00[];
extern const ET9U8 ET9FARDATA l0736b00[];
#endif//_FEATURE_SUPPORT_LANG_SLOVENIAN_
#if defined(_FEATURE_SUPPORT_LANG_ICELANDIC_)
extern const ET9U8 ET9FARDATA l0715b00[];
#endif//_FEATURE_SUPPORT_LANG_ICELANDIC_
#endif /* LOAD_DB_FROM_FILE */

extern InputManager_KDB_Request_Callback g_sInputManager_KDB_Request_Callback;


/*----------------------------------------------------------------------------
 * Local Variables
 *----------------------------------------------------------------------------*/
#ifdef LOAD_DB_FROM_FILE
static ET9U16          curKDBCode = 0;
static FILE           *pKDBFileHandle = NULL;
static KDBFileInfo     KDBFileList[MAX_KDB_LIST];
KDBFileInfo           *pKDBFileList = KDBFileList;
#ifdef USE_HEAP_BUFFER
#define MAX_KDB_SIZE   (1024 * 32) /* 32KB */

static ET9U32          curKDBMaxOffset = 0;
static ET9U8           KDBBuffer[MAX_KDB_SIZE];
#endif /* USE_HEAP_BUFFER */
#endif /* LOAD_DB_FROM_FILE */

/*----------------------------------------------------------------------------
 *  Callback Functions
 *----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
 *
 *   Function: ET9KDBReadData
 *
 *   Synopsis: This function reads KDB data
 *
 *      Input: pKDBInfo             = Pointer to keyboard information structure.
 *             dwOffset             = offset to read from
 *             nNumberOfBytesToRead = Specifies the number of bytes to be read.
 *             pbDst                = buffer for the data
 *             pNumberOfBytesRead   = Pointer to the variable that receives
 *                                    the number of bytes read
 *
 *     Return: ET9STATUS_NONE on success, otherwise return ET9 error code.
 *
 *---------------------------------------------------------------------------*/
#ifdef LOAD_DB_FROM_FILE
void CloseKdbFileHandle()
{
	if (pKDBFileHandle != NULL)
		fclose(pKDBFileHandle);
}

ET9U8 * GetkdbFilePath(ET9U16 kdbCode)
{
	ET9U16 i;
	for (i = 0; i < MAX_KDB_LIST; i++)
	{
		if (kdbCode == KDBFileList[i].kdbCode)
			return KDBFileList[i].filePath;
	}

	return NULL;
}

ET9U32 GetKdbFileSize(ET9U16 kdbCode)
{
	ET9U16 i;
	for (i = 0; i < MAX_KDB_LIST; i++)
	{
		if (kdbCode == KDBFileList[i].kdbCode)
			return KDBFileList[i].fileSize;
	}

	return 0;
}

ET9STATUS ET9FARCALL ET9KDBLoadData(ET9KDBInfo *pKdbInfo, ET9U32 dwKdbNum,
                                    ET9U16  wPageNum)
{
    ET9STATUS          eStatus        = ET9STATUS_NONE;

    KDBIMEInfo * const pIME = (KDBIMEInfo*)pKdbInfo->pPublicExtension;

    ET9_UNUSED(dwKdbNum);

    char *pcFileName = (char *)GetkdbFilePath(dwKdbNum);
    FILE *pf = fopen(pcFileName, "rb");

    if (!pf) {
        return ET9STATUS_ERROR;
    }

    if (fseek(pf, 0, SEEK_END)) {
        return ET9STATUS_ERROR;
    }

    size_t nSize = ftell(pf);

    rewind(pf);

    ET9U8 *pbContent = (ET9U8*)malloc(nSize);

    if (pbContent) {

        if (fread(pbContent, 1, nSize, pf) == nSize) {

            if (strstr(pcFileName, ".txt")) {

                ET9UINT nLine;

                eStatus = ET9KDB_Load_TextKDB(pKdbInfo,
                                              wPageNum,
                                              pbContent,
                                              (ET9U32)nSize,
                                              &nLine);
            }
            else {

                ET9UINT nLine;
                ET9UINT nUnknowns;
                ET9KdbXmlKeyboardInfo sKeyboardLayout;

                eStatus = ET9KDB_Load_XmlKDB(pKdbInfo,
                                             pIME->wKeyboardWidth,
                                             pIME->wKeyboardHeight,
                                             wPageNum,
                                             pbContent,
                                             (ET9U32)nSize,
                                             &sKeyboardLayout,
                                             &nUnknowns,
                                             &nLine);
            }
        }
        else {
            eStatus = ET9STATUS_ERROR;
        }

        free(pbContent);
    }
    else {
        eStatus = ET9STATUS_ERROR;
    }

    fclose(pf);

    //ET9KDB_Load_SetSmartTouch(pKdbInfo, TRUE, 0.8f);
    return eStatus;
}

ET9STATUS ET9FARCALL ET9KDBReadData(ET9KDBInfo *pKdbInfo, ET9U32 dwOffset,
                                    ET9U32  dwNumberOfBytesToRead,
                                    ET9U8  *pbDst,
                                    ET9U32 *pdwNumberOfBytesRead)
{
	ET9STATUS          wStatus        = ET9STATUS_NONE;
	ET9U32             dwBytesRead    = 0;
	ET9U16             kdbCode        = 0;
#ifdef USE_HEAP_BUFFER
    ET9U32             dwSrcSize      = 0;
	ET9U8 ET9FARDATA  *pSrc;
#endif /* USE_HEAP_BUFFER */

	*pdwNumberOfBytesRead = 0;
	kdbCode = pKdbInfo->dwKdbNum;

	if (pKdbInfo->dwKdbNum != curKDBCode || pKDBFileHandle == NULL)
	{
		if (pKDBFileHandle != NULL)
		{
			fclose(pKDBFileHandle);
			pKDBFileHandle = NULL;
		}

		pKDBFileHandle = fopen((char *)GetkdbFilePath(kdbCode), "r");

		if (pKDBFileHandle == NULL)
		{
			wStatus = ET9STATUS_READ_DB_FAIL;
			return wStatus;
		}
#ifdef USE_HEAP_BUFFER
		memset(KDBBuffer, 0x00, sizeof(KDBBuffer));
		curKDBMaxOffset = GetKdbFileSize(kdbCode);

		dwBytesRead = fread(KDBBuffer, sizeof(ET9U8), curKDBMaxOffset, pKDBFileHandle);

		if (dwBytesRead <= 0)
		{
			wStatus = ET9STATUS_READ_DB_FAIL;
			return wStatus;
		}

		fclose(pKDBFileHandle);
#endif
	}

#ifdef USE_HEAP_BUFFER
	if ((dwOffset + dwNumberOfBytesToRead) > curKDBMaxOffset)
		dwSrcSize = curKDBMaxOffset - dwOffset;
	else
		dwSrcSize = dwNumberOfBytesToRead;

	if (dwOffset < curKDBMaxOffset)
	{
		pSrc = &KDBBuffer[dwOffset];
		*pdwNumberOfBytesRead = dwSrcSize;

		while (dwSrcSize--)
			*pbDst++ = *pSrc++;
	}
#else /* USE_HEAP_BUFFER */
	if (fseek(pKDBFileHandle, dwOffset, SEEK_SET) == -1)
		return wStatus;

	dwBytesRead = fread(pbDst, sizeof(ET9U8), dwNumberOfBytesToRead, pKDBFileHandle);

	if (dwBytesRead > 0)
		*pdwNumberOfBytesRead = dwBytesRead;

	//if (pKDBFileHandle != NULL)
	//{
	//	fclose(pKDBFileHandle);
	//	pKDBFileHandle = NULL;
	//}
#endif /* USE_HEAP_BUFFER */

	curKDBCode = kdbCode;

	return wStatus;
}

#else /* LOAD_DB_FROM_FILE */
ET9STATUS ET9FARCALL ET9KDBReadData(ET9KDBInfo *pKdbInfo, ET9U32 dwOffset,
                                    ET9U32  dwNumberOfBytesToRead,
                                    ET9U8  *pbDst,
                                    ET9U32 *pdwNumberOfBytesRead)
{
    ET9STATUS          wStatus = ET9STATUS_NONE;
    ET9U8 ET9FARDATA   *pBlock;
    ET9U8 ET9FARDATA   *pSrc;
    ET9U32             dwBlockSize;
    ET9U32             dwSrcSize;
    ET9U32             dwBlockOffset;
    ET9U32             dwSrcOffset;

    *pdwNumberOfBytesRead = 0;

    while (dwNumberOfBytesToRead) {
        pBlock = NULL;
        dwBlockSize = 0;
        dwSrcOffset = 0;

        switch (pKdbInfo->dwKdbNum) {
#if defined(_FEATURE_SUPPORT_LANG_AZERBAIJANI_)
				case ( 6 * 256) + 71 : /* Azerbaijani */
            if (dwOffset <   2306) {pBlock = (ET9U8 ET9FARDATA *)l0671b00; dwBlockSize = 2306; dwSrcOffset = 0;}
            break;
        case ( 9 * 256) + 71 : /* Azerbaijani */
            if (dwOffset <  15360) {pBlock = (ET9U8 ET9FARDATA *)l0971b00; dwBlockSize = 15360; dwSrcOffset = 0;}
            else if (dwOffset <  30720) {pBlock = (ET9U8 ET9FARDATA *)l0971b01; dwBlockSize = 15360; dwSrcOffset = 15360;}
            else if (dwOffset <  40130) {pBlock = (ET9U8 ET9FARDATA *)l0971b02; dwBlockSize = 9410; dwSrcOffset = 30720;}
            break;
#endif //_FEATURE_SUPPORT_LANG_AZERBAIJANI_

#if defined(_FEATURE_SUPPORT_LANG_ARMENIAN_)
				case ( 6 * 256) + 90 : /* Armenian */
            if (dwOffset <   2330) {pBlock = (ET9U8 ET9FARDATA *)l0690b00; dwBlockSize = 2330; dwSrcOffset = 0;}
            break;
        case ( 9 * 256) + 90 : /* Armenian */
            if (dwOffset <  15360) {pBlock = (ET9U8 ET9FARDATA *)l0990b00; dwBlockSize = 15360; dwSrcOffset = 0;}
            else if (dwOffset <  30720) {pBlock = (ET9U8 ET9FARDATA *)l0990b01; dwBlockSize = 15360; dwSrcOffset = 15360;}
            else if (dwOffset <  46080) {pBlock = (ET9U8 ET9FARDATA *)l0990b02; dwBlockSize = 15360; dwSrcOffset = 30720;}
            else if (dwOffset <  60554) {pBlock = (ET9U8 ET9FARDATA *)l0990b03; dwBlockSize = 14474; dwSrcOffset = 46080;}
            break;
#endif //_FEATURE_SUPPORT_LANG_ARMENIAN_

#if defined(_FEATURE_SUPPORT_LANG_GEORGIAN_)
				case ( 6 * 256) + 96 : /* Georgian */
            if (dwOffset <   2306) {pBlock = (ET9U8 ET9FARDATA *)l0696b00; dwBlockSize = 2306; dwSrcOffset = 0;}
            break;
        case ( 9 * 256) + 96 : /* Georgian */
            if (dwOffset <  15360) {pBlock = (ET9U8 ET9FARDATA *)l0996b00; dwBlockSize = 15360; dwSrcOffset = 0;}
            else if (dwOffset <  30720) {pBlock = (ET9U8 ET9FARDATA *)l0996b01; dwBlockSize = 15360; dwSrcOffset = 15360;}
            else if (dwOffset <  40134) {pBlock = (ET9U8 ET9FARDATA *)l0996b02; dwBlockSize = 9414; dwSrcOffset = 30720;}
            break;
#endif //_FEATURE_SUPPORT_LANG_GEORGIAN_
        	
//////////////////////////////////////
#if defined(_FEATURE_SUPPORT_LANG_FARSI_)		
        case ( 6 * 256) + 41 : /* Farsi *//* Phonepad*/
            if (dwOffset <   1802) {pBlock = (ET9U8 ET9FARDATA *)l0641b00; dwBlockSize = 1802; dwSrcOffset = 0;}
            break;

        case ( 8 * 256) + 41 : /* Farsi *//* Qwerty */
           if (dwOffset <  26940) {pBlock = (ET9U8 ET9FARDATA *)l0841b00; dwBlockSize = 26940; dwSrcOffset = 0;}
            break;
#endif
///////////////////////////////////////
#if defined(_FEATURE_SUPPORT_LANG_ARABIC_)		
        case ( 6 * 256) +  1 : /* Arabic *//* Phonepad*/
            if (dwOffset <   2250) {pBlock = (ET9U8 ET9FARDATA *)l0601b00; dwBlockSize = 2250; dwSrcOffset = 0;}
            break;

        case ( 8 * 256) +  1 : /* Arabic *//* Qwerty */
           if (dwOffset <  26952) {pBlock = (ET9U8 ET9FARDATA *)l0801b00; dwBlockSize = 26952; dwSrcOffset = 0;}
            break;
#endif
#if defined(_FEATURE_SUPPORT_LANG_URDU_)			
		case ( 6 * 256) + 32 : /* Urdu *//* Phonepad*/
            if (dwOffset <   2218) {pBlock = (ET9U8 ET9FARDATA *)l0632b00; dwBlockSize = 2218; dwSrcOffset = 0;}
            break;

		case ( 8 * 256) + 32 : /* Urdu */ /* Qwerty */
            if (dwOffset <  11300) {pBlock = (ET9U8 ET9FARDATA *)l0832b00; dwBlockSize = 11300; dwSrcOffset = 0;}
            break;
#endif
#if defined(_FEATURE_SUPPORT_LANG_HEBREW_)		
        case ( 6 * 256) +  13 : /* Hebrew *//* Phonepad*/
            if (dwOffset <   1914) {pBlock = (ET9U8 ET9FARDATA *)l0613b00; dwBlockSize = 1914; dwSrcOffset = 0;}
            break;

		case ( 8 * 256) + 13 : /* Hebrew */
            if (dwOffset <  26926) {pBlock = (ET9U8 ET9FARDATA *)l0813b00; dwBlockSize = 26926; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_HEBREW_
#if defined(_FEATURE_SUPPORT_LANG_BULGARIAN_)
        case ( 7 * 256) +  2 : /* Bulgarian *//* Qwerty */
            if (dwOffset <    667) {pBlock = (ET9U8 ET9FARDATA *)l0702b00; dwBlockSize = 667; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  2 : /* Bulgarian *//* Phonepad*/
            if (dwOffset <    359) {pBlock = (ET9U8 ET9FARDATA *)l0602b00; dwBlockSize = 359; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_BULGARIAN_
#if defined(_FEATURE_SUPPORT_LANG_CROATIAN_)
        case ( 7 * 256) + 89 : /* Croatian *//* Qwerty */
            if (dwOffset <    613) {pBlock = (ET9U8 ET9FARDATA *)l0789b00; dwBlockSize = 613; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 89 : /* Croatian *//* Keypad */
            if (dwOffset <   1562) {pBlock = (ET9U8 ET9FARDATA *)l0589b00; dwBlockSize = 1562; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 89 : /* Croatian *//* Phonepad*/
            if (dwOffset <    449) {pBlock = (ET9U8 ET9FARDATA *)l0689b00; dwBlockSize = 449; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_CROATIAN_
#if defined(_FEATURE_SUPPORT_LANG_CZECH_)
        case ( 7 * 256) +  5 : /* Czech *//* Qwerty */
            if (dwOffset <    627) {pBlock = (ET9U8 ET9FARDATA *)l0705b00; dwBlockSize = 627; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) +  5 : /* Czech *//* Keypad */
            if (dwOffset <   1618) {pBlock = (ET9U8 ET9FARDATA *)l0505b00; dwBlockSize = 1618; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  5 : /* Czech *//* Phonepad*/
            if (dwOffset <    463) {pBlock = (ET9U8 ET9FARDATA *)l0605b00; dwBlockSize = 463; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_CZECH_
#if defined(_FEATURE_SUPPORT_LANG_DANISH_)
        case ( 7 * 256) +  6 : /* Danish *//* Qwerty */
            if (dwOffset <    648) {pBlock = (ET9U8 ET9FARDATA *)l0706b00; dwBlockSize = 648; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) +  6 : /* Danish *//* Keypad */
            if (dwOffset <   1482) {pBlock = (ET9U8 ET9FARDATA *)l0506b00; dwBlockSize = 1482; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  6 : /* Danish *//* Phonepad*/
            if (dwOffset <    429) {pBlock = (ET9U8 ET9FARDATA *)l0606b00; dwBlockSize = 429; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_DANISH_
#if defined(_FEATURE_SUPPORT_LANG_DUTCH_)
        case ( 7 * 256) + 19 : /* Dutch *//* Qwerty */
            if (dwOffset <    609) {pBlock = (ET9U8 ET9FARDATA *)l0719b00; dwBlockSize = 609; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 19 : /* Dutch *//* Keypad */
            if (dwOffset <   1546) {pBlock = (ET9U8 ET9FARDATA *)l0519b00; dwBlockSize = 1546; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 19 : /* Dutch *//* Phonepad*/
            if (dwOffset <    445) {pBlock = (ET9U8 ET9FARDATA *)l0619b00; dwBlockSize = 445; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_DUTCH_
#if defined(_FEATURE_SUPPORT_LANG_ENGLISH_)
        case ( 7 * 256) +  9 : /* English *//* Qwerty */
            if (dwOffset <  12094) {pBlock = (ET9U8 ET9FARDATA *)l0709b00; dwBlockSize = 12094; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) +  9 : /* English *//* Keypad */
            if (dwOffset <   1370) {pBlock = (ET9U8 ET9FARDATA *)l0509b00; dwBlockSize = 1370; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  9 : /* English *//* Phonepad*/
            if (dwOffset <   1658) {pBlock = (ET9U8 ET9FARDATA *)l0609b00; dwBlockSize = 1658; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_ENGLISH_
#if defined(_FEATURE_SUPPORT_LANG_FINNISH_)
        case ( 7 * 256) + 11 : /* Finnish *//* Qwerty */
            if (dwOffset <    632) {pBlock = (ET9U8 ET9FARDATA *)l0711b00; dwBlockSize = 632; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 11 : /* Finnish *//* Keypad */
            if (dwOffset <   1418) {pBlock = (ET9U8 ET9FARDATA *)l0511b00; dwBlockSize = 1418; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 11 : /* Finnish *//* Phonepad*/
            if (dwOffset <    413) {pBlock = (ET9U8 ET9FARDATA *)l0611b00; dwBlockSize = 413; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_FINNISH_
#if defined(_FEATURE_SUPPORT_LANG_FRENCH_)
        case ( 7 * 256) + 12 : /* French *//* Qwerty */
            if (dwOffset <    607) {pBlock = (ET9U8 ET9FARDATA *)l0712b00; dwBlockSize = 607; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 12 : /* French *//* Keypad */
            if (dwOffset <   1538) {pBlock = (ET9U8 ET9FARDATA *)l0512b00; dwBlockSize = 1538; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 12 : /* French *//* Phonepad*/
            if (dwOffset <    443) {pBlock = (ET9U8 ET9FARDATA *)l0612b00; dwBlockSize = 443; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_FRENCH_
#if defined(_FEATURE_SUPPORT_LANG_GERMAN_)
        case ( 7 * 256) +  7 : /* German *//* Qwerty */
            if (dwOffset <    581) {pBlock = (ET9U8 ET9FARDATA *)l0707b00; dwBlockSize = 581; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) +  7 : /* German *//* Keypad */
            if (dwOffset <   1434) {pBlock = (ET9U8 ET9FARDATA *)l0507b00; dwBlockSize = 1434; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  7 : /* German *//* Phonepad*/
            if (dwOffset <    417) {pBlock = (ET9U8 ET9FARDATA *)l0607b00; dwBlockSize = 417; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_GERMAN_
#if defined(_FEATURE_SUPPORT_LANG_GREEK_)
        case ( 7 * 256) +  8 : /* Greek *//* Qwerty */
            if (dwOffset <    630) {pBlock = (ET9U8 ET9FARDATA *)l0708b00; dwBlockSize = 630; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) +  8 : /* Greek *//* Keypad */
            if (dwOffset <   1350) {pBlock = (ET9U8 ET9FARDATA *)l0508b00; dwBlockSize = 1350; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) +  8 : /* Greek *//* Phonepad*/
            if (dwOffset <    365) {pBlock = (ET9U8 ET9FARDATA *)l0608b00; dwBlockSize = 365; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_GREEK_
#if defined(_FEATURE_SUPPORT_LANG_HUNGARIAN_)
        case ( 7 * 256) + 14 : /* Hungarian *//* Qwerty */
            if (dwOffset <    645) {pBlock = (ET9U8 ET9FARDATA *)l0714b00; dwBlockSize = 645; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 14 : /* Hungarian *//* Keypad */
            if (dwOffset <   1690) {pBlock = (ET9U8 ET9FARDATA *)l0514b00; dwBlockSize = 1690; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 14 : /* Hungarian *//* Phonepad*/
            if (dwOffset <    481) {pBlock = (ET9U8 ET9FARDATA *)l0614b00; dwBlockSize = 481; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_HUNGARIAN_
#if defined(_FEATURE_SUPPORT_LANG_ITALIAN_)
        case ( 7 * 256) + 16 : /* Italian *//* Qwerty */
            if (dwOffset <    577) {pBlock = (ET9U8 ET9FARDATA *)l0716b00; dwBlockSize = 577; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 16 : /* Italian *//* Keypad */
            if (dwOffset <   1418) {pBlock = (ET9U8 ET9FARDATA *)l0516b00; dwBlockSize = 1418; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 16 : /* Italian *//* Phonepad*/
            if (dwOffset <    413) {pBlock = (ET9U8 ET9FARDATA *)l0616b00; dwBlockSize = 413; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_ITALIAN_
#if defined(_FEATURE_SUPPORT_LANG_NORWEGIAN_)
        case ( 7 * 256) + 20 : /* Norwegian *//* Qwerty */
            if (dwOffset <    648) {pBlock = (ET9U8 ET9FARDATA *)l0720b00; dwBlockSize = 648; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 20 : /* Norwegian *//* Keypad */
            if (dwOffset <   1482) {pBlock = (ET9U8 ET9FARDATA *)l0520b00; dwBlockSize = 1482; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 20 : /* Norwegian *//* Phonepad*/
            if (dwOffset <    429) {pBlock = (ET9U8 ET9FARDATA *)l0620b00; dwBlockSize = 429; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_NORWEGIAN_
#if defined(_FEATURE_SUPPORT_LANG_POLISH_)
        case ( 7 * 256) + 21 : /* Polish *//* Qwerty */
            if (dwOffset <    627) {pBlock = (ET9U8 ET9FARDATA *)l0721b00; dwBlockSize = 627; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 21 : /* Polish *//* Keypad */
            if (dwOffset <   1618) {pBlock = (ET9U8 ET9FARDATA *)l0521b00; dwBlockSize = 1618; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 21 : /* Polish *//* Phonepad*/
            if (dwOffset <    463) {pBlock = (ET9U8 ET9FARDATA *)l0621b00; dwBlockSize = 463; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_POLISH_
#if defined(_FEATURE_SUPPORT_LANG_PORTUGUESE_)
        case ( 7 * 256) + 22 : /* Portuguese *//* Qwerty */
            if (dwOffset <    593) {pBlock = (ET9U8 ET9FARDATA *)l0722b00; dwBlockSize = 593; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 22 : /* Portuguese *//* Keypad */
            if (dwOffset <   1482) {pBlock = (ET9U8 ET9FARDATA *)l0522b00; dwBlockSize = 1482; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 22 : /* Portuguese *//* Phonepad*/
            if (dwOffset <    429) {pBlock = (ET9U8 ET9FARDATA *)l0622b00; dwBlockSize = 429; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_PORTUGUESE_
#if defined(_FEATURE_SUPPORT_LANG_ROMANIAN_)
        case ( 7 * 256) + 24 : /* Romanian *//* Qwerty */
            if (dwOffset <    597) {pBlock = (ET9U8 ET9FARDATA *)l0724b00; dwBlockSize = 597; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 24 : /* Romanian *//* Keypad */
            if (dwOffset <   1498) {pBlock = (ET9U8 ET9FARDATA *)l0524b00; dwBlockSize = 1498; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 24 : /* Romanian *//* Phonepad*/
            if (dwOffset <    433) {pBlock = (ET9U8 ET9FARDATA *)l0624b00; dwBlockSize = 433; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_ROMANIAN_
#if defined(_FEATURE_SUPPORT_LANG_RUSSIAN_)
        case ( 7 * 256) + 25 : /* Russian *//* Qwerty */
            if (dwOffset <    669) {pBlock = (ET9U8 ET9FARDATA *)l0725b00; dwBlockSize = 669; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 25 : /* Russian *//* Keypad */
            if (dwOffset <   1406) {pBlock = (ET9U8 ET9FARDATA *)l0525b00; dwBlockSize = 1406; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 25 : /* Russian *//* Phonepad*/
            if (dwOffset <    417) {pBlock = (ET9U8 ET9FARDATA *)l0625b00; dwBlockSize = 417; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_RUSSIAN_
#if defined(_FEATURE_SUPPORT_LANG_SPANISH_)
        case ( 7 * 256) + 10 : /* Spanish *//* Qwerty */
            if (dwOffset <    583) {pBlock = (ET9U8 ET9FARDATA *)l0710b00; dwBlockSize = 583; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 10 : /* Spanish *//* Keypad */
            if (dwOffset <   1442) {pBlock = (ET9U8 ET9FARDATA *)l0510b00; dwBlockSize = 1442; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 10 : /* Spanish *//* Phonepad*/
            if (dwOffset <    419) {pBlock = (ET9U8 ET9FARDATA *)l0610b00; dwBlockSize = 419; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_SPANISH_
#if defined(_FEATURE_SUPPORT_LANG_SWEDISH_)
        case ( 7 * 256) + 29 : /* Swedish *//* Qwerty */
            if (dwOffset <    632) {pBlock = (ET9U8 ET9FARDATA *)l0729b00; dwBlockSize = 632; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 29 : /* Swedish *//* Keypad */
            if (dwOffset <   1418) {pBlock = (ET9U8 ET9FARDATA *)l0529b00; dwBlockSize = 1418; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 29 : /* Swedish *//* Phonepad*/
            if (dwOffset <    413) {pBlock = (ET9U8 ET9FARDATA *)l0629b00; dwBlockSize = 413; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_SWEDISH_
#if defined(_FEATURE_SUPPORT_LANG_TURKISH_)
        case ( 7 * 256) + 31 : /* Turkish *//* Qwerty */
            if (dwOffset <    637) {pBlock = (ET9U8 ET9FARDATA *)l0731b00; dwBlockSize = 637; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 31 : /* Turkish *//* Keypad */
            if (dwOffset <   1498) {pBlock = (ET9U8 ET9FARDATA *)l0531b00; dwBlockSize = 1498; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 31 : /* Turkish *//* Phonepad*/
            if (dwOffset <    415) {pBlock = (ET9U8 ET9FARDATA *)l0631b00; dwBlockSize = 415; dwSrcOffset = 0;}
            break;
            
        //case ( 6 * 256) + 31 : /* Turkish *//* Phonepad*/
        //    if (dwOffset <    480) {pBlock = (ET9U8 ET9FARDATA *)l0631b00; dwBlockSize = 480; dwSrcOffset = 0;}
        //    break;
#endif//_FEATURE_SUPPORT_LANG_TURKISH_
#if defined(_FEATURE_SUPPORT_LANG_KOREAN_)
        case ( 9 * 256) + 18 : /* Korean *//* Qwerty */
            if (dwOffset <    750) {pBlock = (ET9U8 ET9FARDATA *)l0918b00; dwBlockSize = 750; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 18 : /* Korean *//* Phonepad*/
            if (dwOffset <    322) {pBlock = (ET9U8 ET9FARDATA *)l0618b00; dwBlockSize = 322; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_KOREAN_
#if defined(_FEATURE_SUPPORT_LANG_SLOVAK_)
        case ( 7 * 256) + 27 : /* Slovak *//* Qwerty */
            if (dwOffset <    670) {pBlock = (ET9U8 ET9FARDATA *)l0727b00; dwBlockSize = 670; dwSrcOffset = 0;}
            break;

        case ( 5 * 256) + 27 : /* Slovak *//* Keypad */
            if (dwOffset <   1634) {pBlock = (ET9U8 ET9FARDATA *)l0527b00; dwBlockSize = 1634; dwSrcOffset = 0;}
            break;

        case ( 6 * 256) + 27 : /* Slovak *//* Phonepad*/
            if (dwOffset <    467) {pBlock = (ET9U8 ET9FARDATA *)l0627b00; dwBlockSize = 467; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_SLOVAK_
#if defined(_FEATURE_SUPPORT_LANG_UKRAINIAN_)
        case ( 7 * 256) + 34 : /* Ukrainian *//* Qwerty */
            if (dwOffset <    671) {pBlock = (ET9U8 ET9FARDATA *)l0734b00; dwBlockSize = 671; dwSrcOffset = 0;}
	    break;

        case ( 5 * 256) + 34 : /* Ukrainian */
	    if (dwOffset <    426) {pBlock = (ET9U8 ET9FARDATA *)l0534b00; dwBlockSize = 426; dwSrcOffset = 0;}
	    break;

        case ( 6 * 256) + 34 : /* Ukrainian *//* Phonepad */
            if (dwOffset <    367) {pBlock = (ET9U8 ET9FARDATA *)l0634b00; dwBlockSize = 367; dwSrcOffset = 0;}
	    break;
#endif//_FEATURE_SUPPORT_LANG_UKRAINIAN_
#if defined(_FEATURE_SUPPORT_LANG_ESTONIAN_)
        case ( 7 * 256) + 37 : /* Estonian *//* Qwerty */
            if (dwOffset <    577) {pBlock = (ET9U8 ET9FARDATA *)l0737b00; dwBlockSize = 577; dwSrcOffset = 0;}
            break;
        case ( 6 * 256) + 37 : /* Estonian *//* Phonepad */
            if (dwOffset <    359) {pBlock = (ET9U8 ET9FARDATA *)l0637b00; dwBlockSize = 359; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_ESTONIAN_
#if defined(_FEATURE_SUPPORT_LANG_LATVIAN_)
        case ( 7 * 256) + 38 : /* Latvian *//* Qwerty */
            if (dwOffset <    587) {pBlock = (ET9U8 ET9FARDATA *)l0738b00; dwBlockSize = 587; dwSrcOffset = 0;}
            break;
        case ( 6 * 256) + 38 : /* Latvian *//* Phonepad */
            if (dwOffset <    369) {pBlock = (ET9U8 ET9FARDATA *)l0638b00; dwBlockSize = 369; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_LATVIAN_
#if defined(_FEATURE_SUPPORT_LANG_LITHUANIAN_)
        case ( 7 * 256) + 39 : /* Lithuanian *//* Qwerty */
            if (dwOffset <    583) {pBlock = (ET9U8 ET9FARDATA *)l0739b00; dwBlockSize = 583; dwSrcOffset = 0;}
            break;
        case ( 6 * 256) + 39 : /* Lithuanian *//* Phonepad */
            if (dwOffset <    365) {pBlock = (ET9U8 ET9FARDATA *)l0639b00; dwBlockSize = 365; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_LITHUANIAN_
#if defined(_FEATURE_SUPPORT_LANG_SERBIAN_)
        case ( 7 * 256) + 128 : /* Serbian *//* Qwerty */
            if (dwOffset <    613) {pBlock = (ET9U8 ET9FARDATA *)l07128b00; dwBlockSize = 613; dwSrcOffset = 0;}
            break;
        case ( 6 * 256) + 128 : /* Serbian *//* Phonepad */
            if (dwOffset <    395) {pBlock = (ET9U8 ET9FARDATA *)l06128b00; dwBlockSize = 395; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_SERBIAN_
#if defined(_FEATURE_SUPPORT_LANG_KAZAKH_)
        case ( 7 * 256) + 97 : /* Kazakh */
            if (dwOffset <    669) {pBlock = (ET9U8 ET9FARDATA *)l0797b00; dwBlockSize = 669; dwSrcOffset = 0;}
            break;
        case ( 6 * 256) + 97 : /* Kazakh */
            if (dwOffset <    369) {pBlock = (ET9U8 ET9FARDATA *)l0697b00; dwBlockSize = 369; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_KAZAKH_
#if defined(_FEATURE_SUPPORT_LANG_SLOVENIAN_)
        case ( 6 * 256) + 36 : /* Slovenian */
            if (dwOffset <   1582) {pBlock = (ET9U8 ET9FARDATA *)l0636b00; dwBlockSize = 1582; dwSrcOffset = 0;}
            break;
        case ( 7 * 256) + 36 : /* Slovenian */
            if (dwOffset <    599) {pBlock = (ET9U8 ET9FARDATA *)l0736b00; dwBlockSize = 599; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_SLOVENIAN_
#if defined(_FEATURE_SUPPORT_LANG_ICELANDIC_)
        case ( 7 * 256) + 15 : /* Icelandic */
            if (dwOffset <    636) {pBlock = (ET9U8 ET9FARDATA *)l0715b00; dwBlockSize = 636; dwSrcOffset = 0;}
            break;
#endif//_FEATURE_SUPPORT_LANG_ICELANDIC_
        default :
            wStatus = ET9STATUS_READ_DB_FAIL;
            break;
        }

        if (pBlock == NULL) {
            return wStatus;
        }

        dwBlockOffset = (ET9U32)(dwOffset - dwSrcOffset);
        pSrc = &pBlock[dwBlockOffset];
        if ((dwBlockOffset + dwNumberOfBytesToRead) > dwBlockSize) {
            dwSrcSize = (ET9U32)(dwBlockSize - dwBlockOffset);
        }
        else {
            dwSrcSize = dwNumberOfBytesToRead;
        }
        dwOffset = dwSrcOffset + dwBlockSize;
        dwNumberOfBytesToRead -= dwSrcSize;

        *pdwNumberOfBytesRead += dwSrcSize;

        while (dwSrcSize--) {
            *pbDst++ = *pSrc++;
        }

    }

    return wStatus;

}
#endif /* LOAD_DB_FROM_FILE */

static void HandleTouch(ET9KDBInfo      * const pKdbInfo,
                            ET9WordSymbInfo * const pWordSymbInfo,
                            const ET9BOOL           bFinal)
{
    ET9STATUS eStatus;

    const ET9U8 bCurrIndexInList = ET9_NO_ACTIVE_INDEX;

    ET9SYMB sFunctionKey;

	ET9BOOL bAccept, bAddSpace;
	

	if (g_sInputManager_KDB_Request_Callback.obj == NULL) {
		return ET9STATUS_ERROR;
    }

	(*g_sInputManager_KDB_Request_Callback.env)->CallVoidMethod(g_sInputManager_KDB_Request_Callback.env, g_sInputManager_KDB_Request_Callback.obj, g_sInputManager_KDB_Request_Callback.request_Callback);
    
    /*if (bFinal && bIsTraced) {
        ET9ClearAllSymbs(pWordSymbInfo);
      }*/
}


ET9STATUS ET9FARCALL ET9Handle_KDB_Request(ET9KDBInfo      * const pKdbInfo,
                                           ET9WordSymbInfo * const pWordSymbInfo,
                                           ET9KDB_Request  * const pRequest)
{
	ET9STATUS wStatus = ET9STATUS_NONE;
		 switch (pRequest->eType) {
		
			 case ET9_KDB_REQ_TOUCH_START:
			 case ET9_KDB_REQ_TOUCH_UPDATE:
		
				 /* handle trace snake, key activation etc. here */
		
				 if (pRequest->data.sTouchInfo.bMainTouch) {
					 HandleTouch(pKdbInfo, pWordSymbInfo, 0);
				 }
				 break;
		
			 case ET9_KDB_REQ_TOUCH_DONE:
			 	HandleTouch(pKdbInfo, pWordSymbInfo, 0);
				 //HandleTouch(pKdbInfo, pWordSymbInfo, 1);
				 break;
		
			 case ET9_KDB_REQ_TOUCH_ABORT:
				 break;
		
			 default:
				 break;
		 }
		
		

	return wStatus;
}

ET9STATUS ET9FARCALL ET9ConvertSymb(void * pConvertInfo,
                                    ET9SYMB *psConvertSymb)
{
	ET9STATUS wStatus = ET9STATUS_NONE;

	//TODO

	return wStatus;
}

/*----------------------------------------------------------------------------
 *  Get Functions
 *----------------------------------------------------------------------------*/
#ifdef ET9_FULL_INTERFACE
ET9STATUS ET9FARCALL ET9KDB_GetKDBPageHdr(JNIEnv *env, jclass jcls, ET9KDBPageHdr *wai, jobject jobj)
{
	jclass cls;

	if(env == NULL || wai == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	wai->wLeft = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"));
	wai->wTop = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wTop", "S"));
	wai->wRight = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wRight", "S"));
	wai->wBottom = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"));
	wai->bTotalRegions = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bTotalRegions", "B"));
	wai->dwRegionHdrOffset = (*env)->GetIntField(env, jobj, (*env)->GetFieldID(env, cls, "dwRegionHdrOffset", "I"));

	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_GetKDBRegionHdr(JNIEnv *env, jclass jcls, ET9KDBRegionHdr *wai, jobject jobj)
{
	jclass cls;

	if(env == NULL || wai == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	wai->bRegional = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bRegional", "B"));
	wai->wLeft = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"));
	wai->wTop = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wTop", "S"));
	wai->wRight = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wRight", "S"));
	wai->wBottom = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"));
	wai->bTotalRegions = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bTotalRegions", "B"));
	wai->dwRegionHdrOffset = (*env)->GetIntField(env, jobj, (*env)->GetFieldID(env, cls, "dwRegionHdrOffset", "I"));
	wai->bTotalBlockRows = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bTotalBlockRows", "B"));
	wai->bTotalBlockCols = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bTotalBlockCols", "B"));
	wai->wBlockWidth = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wBlockWidth", "S"));
	wai->wBlockHeight = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wBlockHeight", "S"));
	wai->bBlockX = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bBlockX", "B"));
	wai->bBlockY = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bBlockY", "B"));


	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_GetKDBAction(JNIEnv *env, jclass jcls, ET9KDBAction *wai, jobject jobj)
{
	jclass cls;

	if(env == NULL || wai == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);


	wai->bIsKeyAction = (*env)->GetBooleanField(env, jobj, (*env)->GetFieldID(env, cls, "bIsKeyAction", "Z"));
	wai->bShiftState = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bShiftState", "B"));
	wai->bCurrIndexInList = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bCurrIndexInList", "B"));
	wai->dwCurrChecksum = (*env)->GetIntField(env, jobj, (*env)->GetFieldID(env, cls, "dwCurrChecksum", "I"));
	// TODO
	/*
		wai->wKeyIndex or wai->wX,wai->wY (union type)
	*/
	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_GetKDBPrivate(JNIEnv *env, jclass jcls, ET9KDBPrivate *KbdPrivate, jobject jobj)
{
	jclass cls;
	jobject jobj_PageHdr,jobj_RegionHdr,jobj_Action ;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	KbdPrivate->wPageNum = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wPageNum", "S"));
	KbdPrivate->wPageKeyNum = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wPageKeyNum", "S"));
	KbdPrivate->wLayoutWidth = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wLayoutWidth", "S"));
	KbdPrivate->wLayoutHeight = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wLayoutHeight", "S"));
	KbdPrivate->wPageArrayOffset = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wPageArrayOffset", "S"));
	//Get  ET9KDBPageHdr
	jobj_PageHdr = (*env)->GetObjectField(env, jobj, (*env)->GetFieldID(env, cls, "PageHeader",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBPageHdr;"));
	ET9KDB_GetKDBPageHdr(env, jcls, &KbdPrivate->PageHeader, jobj_PageHdr);
	// Get ET9KDBRegionHdr
	jobj_RegionHdr = (*env)->GetObjectField(env, jobj, (*env)->GetFieldID(env, cls, "RegionHeader",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBRegionHdr;"));
	ET9KDB_GetKDBRegionHdr(env, jcls, &KbdPrivate->RegionHeader, jobj_RegionHdr);
#ifdef ET9_DIRECT_KDB_ACCESS
	// TODO
	/*
	KdbPrivate->pKdbData (ET9U8 ET9FARDATA *)
	KdbPrivate->dwKdbDataSize(ET9U32)
	*/
#endif
	// TODO
	/*
	KdbPrivate->pConvertSymb (ET9CONVERTSYMBCALLBACK)
	KdbPrivate->pConvertSymbInfo(void *)
	*/

	KbdPrivate->bMTLastShiftState = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bMTLastShiftState", "B"));
	KbdPrivate->bMTLastSymbIndex = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bMTLastSymbIndex", "B"));
	KbdPrivate->bMTSymbCount = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bMTSymbCount", "B"));
	KbdPrivate->bMTSymbCountSrc = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bMTSymbCountSrc", "B"));
	KbdPrivate->wMTLastInput = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wMTLastInput", "S"));


	GetShortObjectArray(env,jcls, KbdPrivate->sMTSymbs
		,(*env)->GetObjectField(env, jobj,(*env)->GetFieldID(env, cls, "sMTSymbs", "[S"))
		,ET9_KDB_MAX_MT_SYMBS);
	GetShortObjectArray(env,jcls, KbdPrivate->sMTSymbsSrc
		,(*env)->GetObjectField(env, jobj,(*env)->GetFieldID(env, cls, "sMTSymbsSrc", "[S"))
		,ET9_KDB_MAX_MT_SYMBS);
	GetShortObjectArray(env,jcls, KbdPrivate->sMTSymbsCnv
		,(*env)->GetObjectField(env, jobj,(*env)->GetFieldID(env, cls, "sMTSymbsCnv", "[S"))
		,ET9_KDB_MAX_MT_SYMBS);


	// TODO (CALLBACK)
	/*
	KbdPrivate->pFilterSymb = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbReset = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbCount = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbNext = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbGroup = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbInfo = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	*/

	KbdPrivate->bCurrDiacriticState = (*env)->GetByteField(env, jobj, (*env)->GetFieldID(env, cls, "bCurrDiacriticState", "B"));
	// Get ET9KDBAction
	jobj_Action = (*env)->GetObjectField(env, jobj, (*env)->GetFieldID(env, cls, "sKdbAction",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBAction;"));
	ET9KDB_GetKDBAction(env, jcls, &KbdPrivate->sKdbAction, jobj_Action);

	KbdPrivate->bKDBLoaded = (*env)->GetBooleanField(env, jobj, (*env)->GetFieldID(env, cls, "bKDBLoaded", "Z"));
	KbdPrivate->wInfoInitOK  = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wInfoInitOK", "S"));
	KbdPrivate->wKDBInitOK = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wKDBInitOK", "S"));

	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_GetKDBInfo(JNIEnv *env, jclass jcls, ET9KDBInfo *pKbdInfo, jobject jobj)
{
	jclass cls;
	jobject jobj_Private;
	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	pKbdInfo->dwStateBits = (*env)->GetIntField(env, jobj, (*env)->GetFieldID(env, cls, "dwStateBits", "I"));
	// TODO
	/*
	pKbdInfo-> ET9KDBReadData
	pKdbInfo->ET9Handle_KDB_Request
	*/
	pKbdInfo->dwFirstKdbNum= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wFirstKdbNum", "S"));
	pKbdInfo->wFirstPageNum= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wFirstPageNum", "S"));
	pKbdInfo->dwSecondKdbNum= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wSecondKdbNum", "S"));
	pKbdInfo->wSecondPageNum= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wSecondPageNum", "S"));
	pKbdInfo->dwKdbNum= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wKdbNum", "S"));
	pKbdInfo->wTotalPages= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wTotalPages", "S"));
	// TODO
	/*
	pKbdInfo->pPublicExtension (void pointer)
	*/

	//Get  ET9KDBPrivate
	jobj_Private = (*env)->GetObjectField(env, jobj, (*env)->GetFieldID(env, cls, "Private",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBPrivate;"));
	ET9KDB_GetKDBPrivate(env, jcls, &pKbdInfo->Private, jobj_Private);

	return ET9STATUS_NONE;
}
#endif // ET9_FULL_INTERFACE

#ifdef ET9_LITE_INTERFACE
ET9STATUS ET9FARCALL ET9_GetKeyRegion(JNIEnv *env, jclass jcls, ET9Region *pKeyRegion, jobject jobj)
{
	jclass cls;

	if(env == NULL || pKeyRegion == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	pKeyRegion->wLeft = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"));
	pKeyRegion->wTop = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wTop", "S"));
	pKeyRegion->wRight = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wRight", "S"));
	pKeyRegion->wBottom = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"));


	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9_GetIMEInfo(JNIEnv *env, jclass jcls, KDBIMEInfo *pIMEInfo, jobject jobj)
{
	jclass cls;
	jobject jobj_Private;
	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, jobj);

	pIMEInfo->wKeyboardWidth= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wKeyboardWidth", "S"));
	pIMEInfo->wKeyboardHeight= (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "wKeyboardHeight", "S"));

	return ET9STATUS_NONE;
}
#endif // ET9_LITE_INTERFACE

/*----------------------------------------------------------------------------
 *  Set Functions
 *----------------------------------------------------------------------------*/
#ifdef ET9_FULL_INTERFACE
ET9STATUS ET9FARCALL ET9KDB_SetKDBPageHdr(JNIEnv *env, jclass jcls, jobject *jobj, ET9KDBPageHdr wai)
{
	jclass cls;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, *jobj);

	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"), wai.wLeft);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wTop", "S"), wai.wTop);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wRight", "S"), wai.wRight);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"), wai.wBottom);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bTotalRegions", "B"), wai.bTotalRegions);
	(*env)->SetIntField(env, *jobj, (*env)->GetFieldID(env, cls, "dwRegionHdrOffset", "I"), wai.dwRegionHdrOffset);

	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_SetKDBRegionHdr(JNIEnv *env, jclass jcls, jobject *jobj, ET9KDBRegionHdr wai)
{
	jclass cls;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, *jobj);

	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bRegional", "B"), wai.bRegional);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"), wai.wLeft);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wTop", "S"), wai.wTop);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wRight", "S"), wai.wRight);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"), wai.wBottom);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bTotalRegions", "B"), wai.bTotalRegions);
	(*env)->SetIntField(env, *jobj, (*env)->GetFieldID(env, cls, "dwRegionHdrOffset", "I"), wai.dwRegionHdrOffset);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bTotalBlockRows", "B"), wai.bTotalBlockRows);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bTotalBlockCols", "B"), wai.bTotalBlockCols);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wBlockWidth", "S"), wai.wBlockWidth);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wBlockHeight", "S"), wai.wBlockHeight);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bBlockX", "B"), wai.bBlockX);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bBlockY", "B"), wai.bBlockY);

	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_SetKDBAction(JNIEnv *env, jclass jcls, jobject *jobj, ET9KDBAction wai)
{
	jclass cls;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, *jobj);

	(*env)->SetBooleanField(env, *jobj, (*env)->GetFieldID(env, cls, "bIsKeyAction", "Z"), wai.bIsKeyAction);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bShiftState", "B"), wai.bShiftState);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bCurrIndexInList", "B"), wai.bCurrIndexInList);
	(*env)->SetIntField(env, *jobj, (*env)->GetFieldID(env, cls, "dwCurrChecksum", "I"), wai.dwCurrChecksum);

	// TODO
	/*
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wKeyIndex", "S"), wai.wKeyIndex);
	or
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wX", "S"), wai.wX);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wY", "S"), wai.wY);
	(union type)
	*/
	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_SetKDBPrivate(JNIEnv *env, jclass jcls, jobject *jobj, ET9KDBPrivate KbdPrivate)
{
	jclass cls;
	jobject jobj_PageHdr,jobj_RegionHdr,jobj_Action;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, *jobj);

	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wPageNum", "S"), KbdPrivate.wPageNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wPageKeyNum", "S"), KbdPrivate.wPageKeyNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wLayoutWidth", "S"), KbdPrivate.wLayoutWidth);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wLayoutHeight", "S"), KbdPrivate.wLayoutHeight);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wPageArrayOffset", "S"), KbdPrivate.wPageArrayOffset);
	//Set  ET9KDBPageHdr
	jobj_PageHdr = (*env)->GetObjectField(env, *jobj, (*env)->GetFieldID(env, cls, "PageHeader",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBPageHdr;"));
	ET9KDB_SetKDBPageHdr(env, jcls, &jobj_PageHdr, KbdPrivate.PageHeader);
	// Set ET9KDBRegionHdr
	jobj_RegionHdr = (*env)->GetObjectField(env, *jobj, (*env)->GetFieldID(env, cls, "RegionHeader",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBRegionHdr;"));
	ET9KDB_SetKDBRegionHdr(env, jcls, &jobj_RegionHdr, KbdPrivate.RegionHeader);
#ifdef ET9_DIRECT_KDB_ACCESS
	// TODO
	/*
	KdbPrivate->pKdbData (ET9U8 ET9FARDATA *)
	KdbPrivate->dwKdbDataSize(ET9U32)
	*/
#endif
	// TODO
	/*
	KdbPrivate->pConvertSymb (ET9CONVERTSYMBCALLBACK)
	KdbPrivate->pConvertSymbInfo(void *)
	*/
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bMTLastShiftState", "B"), KbdPrivate.bMTLastShiftState);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bMTLastSymbIndex", "B"), KbdPrivate.bMTLastSymbIndex);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bMTSymbCount", "B"), KbdPrivate.bMTSymbCount);
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bMTSymbCountSrc", "B"), KbdPrivate.bMTSymbCountSrc);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wMTLastInput", "S"), KbdPrivate.wMTLastInput);
	// TODO (Array )
	/*
	KbdPrivate->sMTSymbs = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->sMTSymbsSrc = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->sMTSymbsCnv = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	*/
	SetShortObjectArray(env,jcls
						, (*env)->GetObjectField(env, *jobj,(*env)->GetFieldID(env, cls, "sMTSymbs", "[S"))
						, KbdPrivate.sMTSymbs
						,ET9_KDB_MAX_MT_SYMBS);
	SetShortObjectArray(env,jcls
						, (*env)->GetObjectField(env, *jobj,(*env)->GetFieldID(env, cls, "sMTSymbsSrc", "[S"))
						, KbdPrivate.sMTSymbsSrc
						,ET9_KDB_MAX_MT_SYMBS);
	SetShortObjectArray(env,jcls
						, (*env)->GetObjectField(env, *jobj,(*env)->GetFieldID(env, cls, "sMTSymbsCnv", "[S"))
						, KbdPrivate.sMTSymbsCnv
						,ET9_KDB_MAX_MT_SYMBS);



	// TODO (CALLBACK)
	/*
	KbdPrivate->pFilterSymb = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbReset = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbCount = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbNext = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbGroup = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	KbdPrivate->pFilterSymbInfo = (*env)->GetShortField(env, jobj, (*env)->GetFieldID(env, cls, "maxX", "S"));
	*/
	(*env)->SetByteField(env, *jobj, (*env)->GetFieldID(env, cls, "bCurrDiacriticState", "B"), KbdPrivate.bCurrDiacriticState);
	// Set ET9KDBAction
	jobj_Action = (*env)->GetObjectField(env, *jobj, (*env)->GetFieldID(env, cls, "sKdbAction",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBAction;"));
	ET9KDB_SetKDBAction(env, jcls, &jobj_Action, KbdPrivate.sKdbAction);
	(*env)->SetBooleanField(env, *jobj, (*env)->GetFieldID(env, cls, "bKDBLoaded", "Z"), KbdPrivate.bKDBLoaded);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wInfoInitOK", "S"), KbdPrivate.wInfoInitOK);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wKDBInitOK", "S"), KbdPrivate.wKDBInitOK);

	return ET9STATUS_NONE;
}

ET9STATUS ET9FARCALL ET9KDB_SetKDBInfo(JNIEnv *env, jclass jcls, jobject *jobj, ET9KDBInfo pKbdInfo)
{
	jclass cls;
	jobject jobj_Private;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env, *jobj);

	(*env)->SetIntField(env, *jobj, (*env)->GetFieldID(env, cls, "dwStateBits", "I"), pKbdInfo.dwStateBits);
	// TODO
	/*
	pKbdInfo-> ET9KDBReadData
	pKdbInfo->ET9Handle_KDB_Request
	*/
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wFirstKdbNum", "S"), pKbdInfo.dwFirstKdbNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wFirstPageNum", "S"), pKbdInfo.wFirstPageNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wSecondKdbNum", "S"), pKbdInfo.dwSecondKdbNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wSecondPageNum", "S"), pKbdInfo.wSecondPageNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wKdbNum", "S"), pKbdInfo.dwKdbNum);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wTotalPages", "S"), pKbdInfo.wTotalPages);
	// TODO
	/*
	pKbdInfo->pPublicExtension (void pointer)
	*/
	//Set  ET9KDBPrivate
	jobj_Private = (*env)->GetObjectField(env, *jobj, (*env)->GetFieldID(env, cls, "Private",   "Lcom/xt9/core/Xt9Datatype$S_ET9KDBPrivate;"));
	ET9KDB_SetKDBPrivate(env, jcls, &jobj_Private, pKbdInfo.Private);

	return ET9STATUS_NONE;
}
#endif // ET9_FULL_INTERFACE

#ifdef ET9_LITE_INTERFACE
ET9STATUS ET9FARCALL ET9_SetKeyRegion(JNIEnv *env, jclass jcls, jobject *jobj, ET9Region pKeyRegion)
{
	jclass cls;

	if(env == NULL || jobj == NULL)
		return ET9STATUS_INVALID_MEMORY;

	cls = (*env)->GetObjectClass(env,* jobj);

	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wLeft", "S"), pKeyRegion.wLeft);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wTop", "S"), pKeyRegion.wTop);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wRight", "S"), pKeyRegion.wRight);
	(*env)->SetShortField(env, *jobj, (*env)->GetFieldID(env, cls, "wBottom", "S"), pKeyRegion.wBottom);

	return ET9STATUS_NONE;
}
#endif // ET9_LITE_INTERFACE
#endif // ET9_KDB_MODULE
