/*
Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions: The above copyright notice and this
permission notice shall be included in all copies or substantial
portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.


Except as contained in this notice, the names of The Open Group and/or
Sun Microsystems, Inc. shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without prior
written authorization from The Open Group and/or Sun Microsystems,
Inc., as applicable.


X Window System is a trademark of The Open Group

OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
logo, LBX, X Window System, and Xinerama are trademarks of the Open
Group. All other trademarks and registered trademarks mentioned herein
are the property of their respective owners. No right, title or
interest in or to any trademark, service mark, logo or trade name of
Sun Microsystems, Inc. or its licensors is granted.

*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/Xutil.h>
#include <X11/Xcms.h>
#include <X11/Xprotostr.h>
#include <assert.h>
#include <locale.h>
#include <dlfcn.h>
#include <thread.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <Xm/XmAll.h>

#include "XSunExt.h"
#include "XSunIMProt.h"
#include "XSunIMMthd.h"

#include "GeneType.h"
#include "XAuxMethods.h"

#ifdef	notdef
#include "PutXpm.h"
#include "SkbXpms.h"      /* Contain all xpm data */
#endif

const int PUNCTUATION_STATUS   = 1;
const int SOFTKEYBOARD_LAYOUT  = 2;
const int BUTTON_NUMBER = 3;

#define  SKB_SYMBSCIENT     0
#define  SKB_SERIESONE      1
#define  SKB_SERIESTWO      2
#define  SKB_SERIESTHREE    3
#define  SKB_SERIESFOUR     4
#define  SKB_GREECE         5
#define  SKB_RUSSIAN        6
#define  SKB_PYSYM          7
#define  SKB_JAPPIN         8
#define  SKB_JAPPIAN        9
#define  SKB_TABSYMB        10
#define  SKB_GBKEXTSYM1     11
#define  SKB_GBKEXTSYM2     12
#define  SKB_HALFWID        13
#define  SKB_FULLWID        14

#define  TOTAL_SKB          15

#define  PUNCT_CHINESE      0
#define  PUNCT_ENGLISH      1

#define  TOTAL_PUNCT        2

static int nDebugInt = 0;           /* For Debug Message */
/*
char   szAttrNames[17][30] = {      /* For Debug Message 
	"XAUX_DISPLAY",
	"XAUX_SCREENNUM",
	"XAUX_HTTWINDOW",
	"XAUX_FONTSET",
	"XAUX_AREA",
	"XAUX_AREANEEDED",
	"XAUX_COLORMAP",
	"XAUX_STDCOLORMAP",
	"XAUX_FOREGROUND",
	"XAUX_BACKGROUND",
	"XAUX_BACKGROUNDPIXMAP",
	"XAUX_LOCATION",
	"XAUX_FONTNAME",
	"XAUX_CURSOR",
	"XAUX_REPLYCALLBACK",
	"XAUX_REPLYCLIENTDATA",
	"XAUX_GC"
};
*/

/*
** Not used by any part of program!! Scott Ma 05/26, 98
*/
xaux_methods_t xaux_methods = {
	XAux_Create,
	XAux_Start,
	XAux_Draw,
	XAux_Done,
	XAux_SetFocus,
	XAux_UnsetFocus,
	XAux_SetValues,
	XAux_GetValues,
	XAux_Destroy
};

XAux_SesDspParaNode  *pgAuxSdpnList = NULL;

static XAux_SesDspParaNode  *PrefixNewNode(int nIcID);
static XAux_SesDspParaNode  *GetNodeAddressByIcID(int nIcID);

static BOOL DestroyNode(int nIcID);
static BOOL SetAuxNodeValues(XAux_SesDspParaNode* pThisSdpn,
                             XAuxAttribute *pAttrArray, int nArraySize);
static BOOL GetAuxNodeValues(XAux_SesDspParaNode* pThisSdpn,
                             XAuxAttribute *pAttrArray, int nArraySize);
							 
static BOOL CreateGUI(XAux_SesDspParaNode *pThisSdpn);
static BOOL MapGUI   (XAux_SesDspParaNode *pThisSdpn);
static BOOL UnmapGUI (XAux_SesDspParaNode *pThisSdpn);

static void aux_event_handler(Display* pDsp, Window wnd, XEvent* pEvent, void* pvCallData);
static void ListXwaStruct(XWindowAttributes *pXwa);

static void UpdateWndBmp1(XAux_SesDspParaNode *pThisSdpn);
static void UpdateWndBmp2(XAux_SesDspParaNode *pThisSdpn);

    Widget toplevel, main_window, aux2_dialog;
    Widget startbutton, sendbutton, donebutton, form, rc;

/*
** Prefix new node in the front of pgAuxSdpnList.
** Is this nIcID already existed in pgAuxSdpnList?
**    YES,  just move this node to the front of List
**    NO,   alloc memory for new node.
*/
static XAux_SesDspParaNode* PrefixNewNode(int nIcID)
{
	XAux_SesDspParaNode   *pNewSdpNode;
	
	/*
	 * It is necessary to determine has this icID already existed in List?
	 * If yes, don't allocate any more memory. Just move this node to the
	 * front of this list. Notice: change ->next correctly.
	 * Not implemented yet! ==> Scott Ma 98-05-29
	 */
	pNewSdpNode = GetNodeAddressByIcID(nIcID);
	if (pNewSdpNode != NULL)
	{
		fprintf(stderr, "Warning:  PrefixNewNode() this node already existed!\n");
		return pNewSdpNode;
	}
	
	pNewSdpNode     = (XAux_SesDspParaNode*)malloc(sizeof(XAux_SesDspParaNode));
	if (pNewSdpNode == NULL)
	{
		fprintf(stderr, "htt: Failed to malloc() in PrefixNewNode().\n");
		exit(False);
	}
	memset(pNewSdpNode, 0x00, sizeof(XAux_SesDspParaNode));
	
	pNewSdpNode->nPuncState = PUNCT_CHINESE;
	pNewSdpNode->nSkbState  = SKB_HALFWID;
	
	pNewSdpNode->nIcID = nIcID;
	pNewSdpNode->next  = NULL;     /* Null */
	
	/* Update pgAuxSdpnList after memory allocation */
	pNewSdpNode->next = pgAuxSdpnList; /* Place this node in the front of List */
	pgAuxSdpnList     = pNewSdpNode;   /* Added by Scott Ma. 98-05-29 */
	
	/*
	 *  Return the full list whose first node is pNewSdpNode. 
	 *  Notice: return pgAuxSdpnList is also right!!
	 */
	return pNewSdpNode;
}


/*
** Search pgAuxSdpnList to return the address of matched nIcID.
** If not found, return NULL
*/
static XAux_SesDspParaNode* GetNodeAddressByIcID(int nIcID)
{
	XAux_SesDspParaNode  *pThisSdpn;
	XAux_SesDspParaNode  *pTmpSdpn;
	
	pThisSdpn = NULL;
	pTmpSdpn  = pgAuxSdpnList;
	
	while (pTmpSdpn)
	{
		if (pTmpSdpn->nIcID == nIcID)
		{
			pThisSdpn = pTmpSdpn;
			break;
		}
		else
			pTmpSdpn  = pTmpSdpn->next;
	}
	
	return pThisSdpn;
}


/*
**  Destroy the specified node in pgAuxSdpnList and 
**  re-assign the ->next field in the previous node
**  to next node.
**
**  |n|---------|x| |n|---------|x| ... |n|---------|x|
**   n --> nIcID,   x --> *next
**
**  Return   TRUE  ===> Successfully Destroyed!
**           FALSE ===> Failed to Destroyed!
*/
static BOOL DestroyNode(int nIcID)
{
	XAux_SesDspParaNode  *pThisSdpn;
	XAux_SesDspParaNode  *pPrevNext;
	int   nFoundFlag;
	
	/* None node in pgAuxSdpnList */
	if (pgAuxSdpnList == NULL)
		return FALSE;
		
	/* The first node is just this one */
	pThisSdpn = pgAuxSdpnList;
	if (pThisSdpn->nIcID == nIcID)
	{
		pgAuxSdpnList = pThisSdpn->next;
		free (pThisSdpn);
		return TRUE;
	}
		
	/* Else, start directly from the 2th node in list */
	pThisSdpn  = pgAuxSdpnList->next;
	pPrevNext  = pgAuxSdpnList;
	nFoundFlag = FALSE;
	
	while (pThisSdpn)
	{
		if (pThisSdpn->nIcID == nIcID)
		{
			pPrevNext->next = pThisSdpn->next;
			free (pThisSdpn);
			nFoundFlag = TRUE;
			break;
		}
		else
		{
			pThisSdpn = pThisSdpn->next;
			pPrevNext = pPrevNext->next;
		}
	}
	
	return nFoundFlag;
}


/*
** The minimum valid value of nArraySize is 1. if 0, return.
*/
static BOOL SetAuxNodeValues(XAux_SesDspParaNode* pThisSdpn, 
                             XAuxAttribute *pAttrArray, int nArraySize)
{
	XAuxAttribute   *pTmpAttr;

	for( ; nArraySize > 0; nArraySize--)
	{
		pTmpAttr = &(pAttrArray[nArraySize - 1]);
		
/*
#ifndef NDEBUG
		if ((pTmpAttr->nAttrID >= 1) && (pTmpAttr->nAttrID <= 17))
		{
			printf ("   ==> SetAuxNodeValues [%02d] %s\n", 
			        pTmpAttr->nAttrID, szAttrNames[pTmpAttr->nAttrID - 1]);

		}
		else
			printf ("   ==> SetAuxNodeValues [%02d] %s\n", 
			        pTmpAttr->nAttrID, "???????");
#endif
*/
		
		switch (pTmpAttr->nAttrID)
		{
		case XAUX_DISPLAY :
			pThisSdpn->pDsp        = (Display *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_SCREENNUM :
			pThisSdpn->nScreenNum  = *(int *)(pTmpAttr->pvValue);
			break;

		case XAUX_HTTWINDOW :
			pThisSdpn->wndHttWin   = *(Window *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_FONTSET :
			pThisSdpn->xfsFontSet  = *(XFontSet *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_AREA :
			pThisSdpn->rectArea    = *(XRectangle *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_AREANEEDED :
			pThisSdpn->rectNeeded  = *(XRectangle *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_COLORMAP :
			pThisSdpn->cmap        = *(Colormap *)(pTmpAttr->pvValue);
			break;

		case XAUX_STDCOLORMAP :
			pThisSdpn->cmapStd     = *(Colormap *)(pTmpAttr->pvValue);
			break;

		case XAUX_FOREGROUND :
			pThisSdpn->fgPix       = *(unsigned long *)(pTmpAttr->pvValue);
			break;

		case XAUX_BACKGROUND :
			pThisSdpn->bgPix       = *(unsigned long *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_LOCATION :
			pThisSdpn->xyPointLoc  = *(xPoint *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_FONTNAME:
			pThisSdpn->pszFontName = (char *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_REPLYCALLBACK :
			pThisSdpn->fpReplyCb   = (void (*)())(pTmpAttr->pvValue);	
			break;
			
		case XAUX_REPLYCLIENTDATA :
			pThisSdpn->pbReplyData = (void *)(pTmpAttr->pvValue);
			break;
			
		case XAUX_GC :
			pThisSdpn->gc          = *(GC *)(pTmpAttr->pvValue);
			break;
			
		default :
			break;
		}
	}
	
	return True;
}


/*
**  The minimum valid value of nArraySize is 1. if 0, return.
**
**  Notice: Invoker must assure that related pAttrArray->nAttrID
**          have already been set!  ==> Scott Ma
**
**  Warning:Only because pgAuxSdpnList is a global variant and
**          were malloced, so we can return the address in this
**          structure!! In C language, cannot return the address
**          of a local variant!!    ==> Scott Ma
*/
static BOOL GetAuxNodeValues(XAux_SesDspParaNode* pThisSdpn, 
                             XAuxAttribute *pAttrArray, int nArraySize)
{
	XAuxAttribute   *pTmpAttr;
	
	for( ; nArraySize > 0; nArraySize--)
	{
		pTmpAttr = &(pAttrArray[nArraySize - 1]);
/*
#ifndef NDEBUG
		if ((pTmpAttr->nAttrID >= 1) && (pTmpAttr->nAttrID <= 17))
		{
			printf ("   ==+++> GetAuxNodeValues [%02d] %s\n", 
			        pTmpAttr->nAttrID, szAttrNames[pTmpAttr->nAttrID - 1]);
		}
		else
			printf ("   ==+++> GetAuxNodeValues [%02d] %s\n", 
			        pTmpAttr->nAttrID, "???????");
#endif
*/
		
		switch (pTmpAttr->nAttrID)
		{
		case XAUX_DISPLAY :
			pTmpAttr->pvValue      = (void *)(pThisSdpn->pDsp);
			pTmpAttr->nLenValue    = sizeof(Display*);
			break;
			
		case XAUX_SCREENNUM :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->nScreenNum);
			pTmpAttr->nLenValue    = sizeof(int);
			break;

		case XAUX_HTTWINDOW :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->wndHttWin);
			pTmpAttr->nLenValue    = sizeof(Window);
			break;
			
		case XAUX_FONTSET :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->xfsFontSet);
			pTmpAttr->nLenValue    = sizeof(XFontSet);
			break;
			
		case XAUX_AREA :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->rectArea);
			pTmpAttr->nLenValue    = sizeof(XRectangle);
			break;
			
		case XAUX_AREANEEDED :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->rectNeeded);
			pTmpAttr->nLenValue    = sizeof(XRectangle);
			break;
			
		case XAUX_COLORMAP :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->cmap);
			pTmpAttr->nLenValue    = sizeof(Colormap);
			break;

		case XAUX_STDCOLORMAP :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->cmapStd);
			pTmpAttr->nLenValue    = sizeof(Colormap);
			break;

		case XAUX_FOREGROUND :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->fgPix);
			pTmpAttr->nLenValue    = sizeof(unsigned long);
			break;

		case XAUX_BACKGROUND :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->bgPix);
			pTmpAttr->nLenValue    = sizeof(unsigned long);
			break;
			
		case XAUX_LOCATION :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->xyPointLoc);
			pTmpAttr->nLenValue    = sizeof(xPoint);
			break;
			
		case XAUX_FONTNAME:
			pTmpAttr->pvValue      = (void *)(pThisSdpn->pszFontName);
			pTmpAttr->nLenValue    = sizeof(char *);
			break;
			
		case XAUX_REPLYCALLBACK :
			pTmpAttr->pvValue      = (void *)(pThisSdpn->fpReplyCb);
			pTmpAttr->nLenValue    = sizeof(void (*)());
			break;
			
		case XAUX_REPLYCLIENTDATA :
			pTmpAttr->pvValue      = (void *)(pThisSdpn->pbReplyData);
			pTmpAttr->nLenValue    = sizeof(void *);
			break;
			
		case XAUX_GC :
			pTmpAttr->pvValue      = (void *)&(pThisSdpn->gc);
			pTmpAttr->nLenValue    = sizeof(GC);
			break;
			
		default :
			break;
		}
	}
	
	return True;
}


/*
**  Notice: During realizeGUI, must set AREANEEDED and LOCATION info.
*/

/*
**  Is this nIcID already existed?
**     1. NO,  PrefixNewNode() to pgAuxSdpnList, and Create GUI
**     2. YES, SetAuxNodeValues() and RealizeGUI().
*/
BOOL XAux_Create(int nIcID, XAuxAttribute *pAttrArray, int nArraySize)
{
	XAux_SesDspParaNode  *pThisSdpn;
	
printf("Creating...nIcID[%d]\n", nIcID);

	pThisSdpn = GetNodeAddressByIcID(nIcID);
	/* Not existed, alloc memory for it */
	if(pThisSdpn == NULL)
	{
		pThisSdpn  = PrefixNewNode(nIcID);
		if (pThisSdpn == NULL)
			return FALSE;
	}
			
	SetAuxNodeValues(pThisSdpn, pAttrArray, nArraySize);
	/* Create GUI, and set ->wndIM, wndBmp1, wndBmp2 ... */

printf("Creating GUI\n");
	CreateGUI(pThisSdpn);

	pThisSdpn->nWndStatus = FALSE;
	
	return TRUE;
}


/*
**  XAux_Start(): start an instance of the auxiliary object
**                [pAcbs] means Pointer to Aux CallBack Struct.
*/
BOOL XAux_Start(int nIcID, XIMAuxStartCallbackStruct *pAcbs)
{
	XAux_SesDspParaNode  *pThisSdpn;

printf("Starting...nIcID[%d]\n", nIcID);

	MapGUI(pThisSdpn);

#ifdef	notdef
	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL) return FALSE;

	UnmapGUI(pThisSdpn);
	pThisSdpn->nWndStatus = FALSE;

	if(pAcbs != NULL) free(pAcbs);
#endif

	return TRUE;
}


/*
**  When the language engine calls iml_make_aux_draw_inst
**       to let the X_auxiliary object to draw something.
*/
BOOL XAux_Draw(int nIcID, XIMAuxDrawCallbackStruct *pAcbs) 
{
	int i;
	XAux_SesDspParaNode  *pThisSdpn;
	int num_int, num_str;
	int * int_ptr;
    XIMText * str_ptr;
    int int_val;
    int str_val;

	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL) return FALSE;

printf("Drawing...nIcID[%d]\n", nIcID);

    num_int = pAcbs->count_integer_values;
    num_str = pAcbs->count_string_values;
    int_ptr = pAcbs->integer_values;
    str_ptr = pAcbs->string_values;

printf("num_int=%d\n", num_int);
printf("num_str=%d\n", num_str);

for(i=0;i<num_int;i++){
	printf("int[%d]=%d\n", i, int_ptr[i]);
}

#ifdef	notdef
    while (num_int--) {
        int_val = *int_ptr;
        switch (int_val) {
            case 1:
                str_val = *(char *)(str_ptr -> string.multi_byte);
		pThisSdpn->nPuncState = str_val;
                break;
            case 2:
                str_val = *(char *)(str_ptr -> string.multi_byte);
		pThisSdpn->nSkbState = str_val;
                break;
	    case 3:
		break;
        }
        int_ptr++;
        str_ptr++;
    }
/*
printf("pThisSdpn->nPuncState = %d, pThisSdpn->nSkbState = %d\n",pThisSdpn->nPuncState, pThisSdpn->nSkbState);
*/
	MapGUI(pThisSdpn);
	pThisSdpn->nWndStatus = TRUE;
	
	free(pAcbs->integer_values);
	free(pAcbs->string_values);
	free(pAcbs);
	/* parse the call_data and do accordingly */
#endif
	return TRUE;
}


/*
**  When the language engine calls iml_make_aux_done_inst 
**    to let the auxiliary object know that the previous
**    draw action is done. 
*/
BOOL XAux_Done(int nIcID, XIMAuxDoneCallbackStruct *pAcbs)
{
	XAux_SesDspParaNode  *pThisSdpn;

/*
printf("Done...nIcID[%d]\n", nIcID);
*/
	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL) return FALSE;

	UnmapGUI(pThisSdpn);
	pThisSdpn->nWndStatus = FALSE;

	if(pAcbs != NULL) free(pAcbs);
	return TRUE;
}


/*
** when a specific xic has the focus
*/
BOOL XAux_SetFocus(int nIcID)
{
	XAux_SesDspParaNode  *pThisSdpn;
/*
printf("SetFocus...nIcID[%d]\n", nIcID);
*/
	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL) return FALSE;
		
	if(pThisSdpn->nWndStatus == TRUE) MapGUI(pThisSdpn);
	else UnmapGUI(pThisSdpn);

	/* parse the call_data and do something accordingly */
	return True;
}


/*
** when a specific xic has lost the focus
*/
BOOL XAux_UnsetFocus(int nIcID)
{
	XAux_SesDspParaNode  *pThisSdpn;
	
/*
printf("UnsetFocus...nIcID[%d]\n", nIcID);
*/
	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL)
		return FALSE;

/*	UnmapGUI(pThisSdpn);

	pThisSdpn->nWndStatus = FALSE;*/
		
	return TRUE;
}


/*
**  The htt_server may set these values after negotiating with 
**  the xaux object using xaux_GetValues.
*/
BOOL XAux_SetValues(int nIcID, XAuxAttribute *pAttrArray, int nArraySize) 
{
	XAux_SesDspParaNode  *pThisSdpn;
	BOOL    status;
	
printf("SetValues...NIcID\n", nIcID);

#ifdef	notdef
	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL)
		return FALSE;
	
	status = SetAuxNodeValues(pThisSdpn, pAttrArray, nArraySize);
#endif
	return status;
}


/*
**  The htt_server may use this method to negotiate with the xaux object 
**  about the preferred settings. It can then go ahead and set the values
**  in the xaux object using xaux_SetValues. 
**  
**  AREA and LOCATION info is important!!  ==> Scott Ma
**  Notice: Invoker must assure that pAttrArray have already
**          set related ->nAttrID !!
*/
BOOL XAux_GetValues(int nIcID, XAuxAttribute *pAttrArray, int nArraySize)
{
	XAux_SesDspParaNode  *pThisSdpn;
	BOOL    status;
	
printf("GetValues...nIcID\n", nIcID);

	pThisSdpn = GetNodeAddressByIcID(nIcID);
	if (pThisSdpn == NULL)
		return FALSE;
		
	status = GetAuxNodeValues(pThisSdpn, pAttrArray, nArraySize);
	return status;
}


/*
**  Define this method so that the htt_server can call this when 
**  xic is destroyed and the corresponding session with xaux 
**  object needs to be destroyed.
*/
BOOL XAux_Destroy(int nIcID)
{
	BOOL    status;
	
/*
printf("Destroying...nIcID\n", nIcID);
*/
	/* remove specified node */
	/* Should Destroy Windows for this nIcID */
	status = DestroyNode (nIcID);
	return status;
}

static BOOL MapGUI(XAux_SesDspParaNode *pThisSdpn)
{
#ifdef	notdef
	UpdateWndBmp1(pThisSdpn);
	UpdateWndBmp2(pThisSdpn);
#else
        XtRealizeWidget(toplevel);
        XtMapWidget(main_window);
#endif
	return TRUE;
}


static BOOL UnmapGUI(XAux_SesDspParaNode *pThisSdpn)
{
#ifdef	notdef
	XUnmapWindow(pThisSdpn->pDsp, pThisSdpn->wndBmp1);
	XUnmapWindow(pThisSdpn->pDsp, pThisSdpn->wndBmp2);
#else
        XtUnmapWidget(main_window);
#endif
	return TRUE;
}

void
cancel_cb(
          Widget w,
          XtPointer clientData,
          XtPointer callData
)
{
    if (clientData) {
        XtUnrealizeWidget((Widget) clientData);
    }
}

void start_cb(Widget, XtPointer, XtPointer);
void start_aux2(Widget);
XtAppContext app_context;
Widget label;

static void * accept_loop(void *client_data);

static BOOL CreateGUI(XAux_SesDspParaNode *pThisSdpn)
{
#ifdef	notdef
	Display  *pDsp;
	Window    wndHttWin;
	int       nScreenNum;
	int       nStatus;
	Window    wndRoot, wndParent, *pwndChilds;
	UINT      nNumChild;
	
	XWindowAttributes *pXwa;

	pDsp       = pThisSdpn->pDsp;	
	wndHttWin  = pThisSdpn->wndHttWin;
	nScreenNum = DefaultScreen(pDsp);
	
	if (pThisSdpn->pDsp != NULL)
	{
		nStatus = XQueryTree(pDsp, wndHttWin, &wndRoot, &wndParent, &pwndChilds, &nNumChild);
		if (nStatus != 0)
		{
			XGetWindowAttributes(pDsp, wndParent, pXwa);
/*
			ListXwaStruct(pXwa);
*/
			pThisSdpn->wndParent = wndParent;
		}
		else
		{
			printf("Error: XAuxMethods failed in XQueryTree()!\n");
			return FALSE;
		}
	}
	
	/* This Window has nothing to do!! */
	pThisSdpn->wndIM = XCreateSimpleWindow(pDsp, wndHttWin,
				pThisSdpn->rectArea.x,
				pThisSdpn->rectArea.y,
				pThisSdpn->rectArea.width,
				pThisSdpn->rectArea.height,
				0,                    /* Border Width */
				pThisSdpn->bgPix,     /* Border Pixel */
				pThisSdpn->bgPix);    /* Background Pixel */
	/**/
	XMapWindow(pDsp, pThisSdpn->wndIM);
	/**/
	
	/* Create and Map Bitmap1 Window */
	pThisSdpn->wndBmp1 = XCreateSimpleWindow (pDsp, wndParent,
				(pXwa->width) - 50, 2,
				16,        /* Width */
				16,        /* Height */
				0,
				WhitePixel(pDsp, nScreenNum),
				WhitePixel(pDsp, nScreenNum));
	
	XSelectInput (pDsp, pThisSdpn->wndBmp1, ExposureMask | ButtonPressMask | VisibilityChangeMask);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp1, Expose, Expose,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp1, ButtonPress, ButtonPress,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp1, VisibilityNotify, VisibilityNotify,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
/*	XMapWindow(pDsp, pThisSdpn->wndBmp1);*/
	
	/* Create and Map Bitmap2 Window */
	pThisSdpn->wndBmp2 = XCreateSimpleWindow (pDsp, wndParent,
	            (pXwa->width) - 30, 2,
	            16,
	            16,
	            0,
	            WhitePixel(pDsp, nScreenNum),
	            WhitePixel(pDsp, nScreenNum));

	XSelectInput (pDsp, pThisSdpn->wndBmp2, ExposureMask | ButtonPressMask | VisibilityChangeMask);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp2, Expose, Expose,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp2, ButtonPress, ButtonPress,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
	_XRegisterFilterByType (pDsp, pThisSdpn->wndBmp2, VisibilityNotify, VisibilityNotify,
	                       (BOOL(*)())aux_event_handler, (void *)pThisSdpn);
/* 	XMapWindow(pDsp, pThisSdpn->wndBmp2); */
	
	XFree(pXwa);
#else
    {
    thread_t tid;
    int argc = 0;
    char **argv = 0;
    Arg args[20];
    int i;
    XtToolkitThreadInitialize();
    XtSetLanguageProc(NULL, NULL, NULL);
    toplevel = XtVaAppInitialize(&app_context,
				 "test",
				 NULL, NULL,
				 &argc, argv,
				 NULL, NULL);
    main_window = XmCreateMainWindow(toplevel, "mainw", NULL, 0);
    XtManageChild(main_window);
    i = 0;
    XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNleftOffset, 10); i++;
    XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNrightOffset, 10); i++;
    XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNtopOffset, 10); i++;
    XtSetArg(args[i], XmNorientation, XmHORIZONTAL); i++;
    rc = XmCreateRowColumn(main_window, "rowc", args, i);
    XtManageChild(rc);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Add Word", XmSTRING_DEFAULT_CHARSET));
    i++;
    startbutton = XmCreatePushButton(rc, "addword", args, i);
    XtAddCallback(startbutton, XmNactivateCallback, start_cb, main_window);
    XtManageChild(startbutton);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Send Data To Engine", XmSTRING_DEFAULT_CHARSET));
    i++;
    sendbutton = XmCreatePushButton(rc, "sendbutton", args, i);
    XtManageChild(sendbutton);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Done", XmSTRING_DEFAULT_CHARSET));
    i++;
    donebutton = XmCreatePushButton(rc, "donebutton", args, i);
    XtManageChild(donebutton);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("DISPLAY RECEIVED DATA", XmSTRING_DEFAULT_CHARSET));
    i++;
    label = XmCreateLabel(rc, "label", args, i);
    XtManageChild(label);

    thr_create(NULL, 0, accept_loop, 0, THR_BOUND, &tid);
    }
#endif
	
    return TRUE;
}

static void *
accept_loop(void *client_data)
{
printf("accept_loo\n");
    XtAppMainLoop((XtAppContext)app_context);
printf("accept_loop exit\n");
    return 0;
}


#ifdef	notdef

static void aux_event_handler(Display* pDsp, Window wnd, XEvent* pEvent, void* pvCallData)
{
	XAux_SesDspParaNode       *pThisSdpn;
	static char  chPuncState, chSkbState, chButtonNo;
	static       XIMAuxDrawCallbackStruct  *pAcbs = NULL;
	int          nIcID;
	
	pThisSdpn = (XAux_SesDspParaNode *)pvCallData;
	if (pThisSdpn != NULL)
	{
		nIcID     = pThisSdpn->nIcID;
		assert(pDsp == pThisSdpn->pDsp); 
		pDsp = pThisSdpn->pDsp;
	}

	switch (pEvent->type)
	{
	case VisibilityNotify :
	case Expose :
		if (wnd == pThisSdpn->wndBmp1)
			UpdateWndBmp1(pThisSdpn);
		else if (wnd == pThisSdpn->wndBmp2)
			UpdateWndBmp2(pThisSdpn);
		break;
		
	case ButtonPress :
		chButtonNo = (char)pEvent->xbutton.button;
		if (pAcbs != NULL) free(pAcbs);
		pAcbs = (XIMAuxDrawCallbackStruct *)malloc(sizeof(XIMAuxDrawCallbackStruct));
		pAcbs->count_integer_values  = 2;
		pAcbs->count_string_values   = 2;
		pAcbs->integer_values = (int *)malloc(sizeof(int) * (pAcbs->count_integer_values));
		pAcbs->string_values = (XIMText *)malloc(sizeof(XIMText) * (pAcbs->count_string_values));
		
		*(pAcbs->integer_values)  = BUTTON_NUMBER;
		pAcbs->string_values->length = 5;
		pAcbs->string_values->encoding_is_wchar = 0;
		pAcbs->string_values->string.multi_byte = (char *)&chButtonNo;
		
		if (wnd == pThisSdpn->wndBmp1)
		{
			chPuncState = (char)pThisSdpn->nPuncState;
			*((pAcbs->integer_values) + 1)  = PUNCTUATION_STATUS;
			((pAcbs->string_values) + 1)->length = 5;
			((pAcbs->string_values) + 1)->encoding_is_wchar = 0;
			((pAcbs->string_values) + 1)->string.multi_byte = (char *)&chPuncState;
		}
		
		if (wnd == pThisSdpn->wndBmp2)
		{
			chSkbState = (char)pThisSdpn->nSkbState;
			*((pAcbs->integer_values) + 1)= SOFTKEYBOARD_LAYOUT;
			((pAcbs->string_values) + 1)->length = 5;
			((pAcbs->string_values) + 1)->encoding_is_wchar = 0;
			((pAcbs->string_values) + 1)->string.multi_byte = (char *)&chSkbState;
		}
		
		pThisSdpn->fpReplyCb(nIcID, pThisSdpn->pbReplyData, pAcbs);
		break;
		
	default :
		break;
	}
	
	return;
}


static void UpdateWndBmp1(XAux_SesDspParaNode *pThisSdpn)
{
	PutXpm(pThisSdpn->pDsp, pThisSdpn->wndBmp1, 0, 0, 
	       PuncXpmArray[pThisSdpn->nPuncState], -1, -1, -1, -1, 0);
		
	XMapWindow(pThisSdpn->pDsp, pThisSdpn->wndBmp1);
}


static void UpdateWndBmp2(XAux_SesDspParaNode *pThisSdpn)
{
	PutXpm(pThisSdpn->pDsp, pThisSdpn->wndBmp2, 0, 0, 
	       SkbXpmArray[pThisSdpn->nSkbState], -1, -1, -1, -1, 0);

	XMapWindow(pThisSdpn->pDsp, pThisSdpn->wndBmp2);
}



static void ListXwaStruct(XWindowAttributes *pXwa)
{
	printf("    pXwa->x     [%04d]\n", pXwa->x);
	printf("    pXwa->y     [%04d]\n", pXwa->y);
	printf("    pXwa->width [%04d]\n", pXwa->width);
	printf("    pXwa->height[%04d]\n", pXwa->height);
	printf("    pXwa->depth [%04d]\n", pXwa->depth);
	printf("    pXwa->map_state: ");
		if(pXwa->map_state == IsUnmapped)
			printf("[IsUnmapped]\n");
		else if(pXwa->map_state == IsUnviewable)
			printf("[IsUnviewable]\n");
		else if(pXwa->map_state == IsViewable)
			printf("[IsViewable]\n");
}
#endif

void
start_cb(
         Widget w,
         XtPointer clientData,
         XtPointer callData
)
{
    start_aux2((Widget) clientData);
}


void
start_aux2(
	   Widget parent
)
{
    Widget button1, button2, rc;
    Widget label1, label2;
    Widget text1, text2;
    Arg args[20];
    int i;

    if (aux2_dialog) {
	XtManageChild(aux2_dialog);
	XtRealizeWidget(aux2_dialog);
	return;
    }
    i = 0;
    XtSetArg(args[i], XmNtitle, "AUX2 DICTIONALY TOOL");
    i++;
    aux2_dialog = XmCreateFormDialog(parent, "dict_dialog", args, i);

    i = 0;
    XtSetArg(args[i], XmNleftAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNrightAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNtopAttachment, XmATTACH_FORM); i++;
    XtSetArg(args[i], XmNorientation, XmHORIZONTAL); i++;
    rc = XmCreateRowColumn(aux2_dialog, "rowc", args, i);
    XtManageChild(rc);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("String:", XmSTRING_DEFAULT_CHARSET)); i++;
    label1 = XmCreateLabel(rc, "label1", args, i);
    XtManageChild(label1);

    i = 0;
    XtSetArg(args[i], XmNcolumns, 15);
    i++;
    text1 = XmCreateTextField(rc, "textfield1", args, i);
    XtManageChild(text1);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Japanese:", XmSTRING_DEFAULT_CHARSET));
    i++;
    label2 = XmCreateLabel(rc, "label2", args, i);
    XtManageChild(label2);

    i = 0;
    XtSetArg(args[i], XmNcolumns, 15);
    i++;
    text2 = XmCreateTextField(rc, "textfield2", args, i);
    XtManageChild(text2);

    i = 0;
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Add", XmSTRING_DEFAULT_CHARSET));
    i++;
    button1 = XmCreatePushButton(rc, "button1", args, i);
    XtManageChild(button1);

    i = 0;
    XtManageChild(button1);
    XtSetArg(args[i], XmNlabelString, XmStringCreate("Cancel", XmSTRING_DEFAULT_CHARSET));
    i++;
    button2 = XmCreatePushButton(rc, "button2", args, i);
    XtAddCallback(button2, XmNactivateCallback, cancel_cb, aux2_dialog);
    XtManageChild(button2);

    XtManageChild(aux2_dialog);
}
