/*
 * Copyright 2003 Sun Microsystems Inc.
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Authors: Karl Park <karl.park@sun.com>
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xmd.h>

#include "xaux_locale.h"
#include "xaux_common.h"
#include "xaux_ext_common.h"
#include "koinput.h"
#include "palette_aux.h"
#include "OptionConfig.h"
#include "kolelog.h"
#include "aux-message.h"
#include "engine-property.h"

/* Define Aux class */
xaux_class_t *xc_ = 0;
int im_ = 0;
int ic_ = 0;


/* Define Aux class */
xaux_class_t xaux_class = {
  XAUX_PALETTE_CLASS_NAME, 1,
  NULL,
  (Window)0, (Window)0,
  (Atom)0, (Atom)0, (Atom)0,
  { (Atom)0 }, ATOM_NUM_PALETTEAUX, 0,
  { (Atom)0 }, ATOM_NUM_PALETTEAUX, 0,
  NULL,
};

int gLocaleID = 0;
Display *gDisplay = NULL;
Window  gWindow  = 0;
KOLE_property *p_engine_property = NULL;

/*  Auxiliary Window User Input Method Information  */
extern PaletteInfoRecord palettecore;

/*
  extern IMEListRec	AllIMEList, SelectedIMEList;
  extern int 		gIMEOptionsNum;
  extern IMEOption_Item	*gIMEOptions[];
*/

void dummy (aux_ext_data_t *aux_ext_data);

void PaletteAux_Set_Options_Request();
void PaletteAux_Connect_To_LE_Request();
void PaletteAux_Lost_Focus_Request();
static void paletteaux_notification_handler();
void PaletteAux_Proc_LE_Set_IMEInfo_Notify();
void PaletteAux_Proc_LE_Update_IMEInfo_Notify();
void palette_process_le_message_switch_conversion ();
void PaletteAux_Proc_LE_Switch_IME_Notify();
void PaletteAux_Proc_LE_Switch_QjBj_Notify();
void PaletteAux_Proc_LE_Switch_Punct_Notify();
void PaletteAux_Proc_LE_Change_Focus_Notify();
void PaletteAux_Proc_LE_Set_IMEInfo_End_Notify(aux_ext_data_t *aux_ext_data);
void PaletteAux_Proc_LE_New_IMEInfo_Notify(aux_ext_data_t *aux_ext_data);
void paletteaux_set_session_property(aux_ext_data_t *aux_ext_data);
void PaletteAux_Proc_LE_Update_KeymapInfo_Notify(aux_ext_data_t *aux_ext_data);
static void PaletteAux_Set_Selection_Owner ();


/*   
     Event Handler 
*/
GdkFilterReturn
xaux_ext_event_handler (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer user_data)
{
  XEvent *xevent = (XEvent *) gdk_xevent;

  switch (xevent->type) {
  case ClientMessage:
    xaux_ext_process_client_message((Display *)gDisplay,
				    (XClientMessageEvent *) xevent);
    break;
  case SelectionClear:
    break;
  }
  return GDK_FILTER_CONTINUE;
}

/*
  xaux_ext_init_classes(): Initialize the Atom of Auxiliary Window.
  It is in ../xaux_common/xaux_ext_common.c
*/
int
xaux_ext_register_classes (GdkWindow *window)
{
  gDisplay = (Display *)GDK_WINDOW_XDISPLAY(window);
  gWindow  = (Window)GDK_WINDOW_XWINDOW(window);
  /* Register aux class */
  int xaux_result =
    xaux_ext_init_classes (gDisplay,
			   (xaux_class_t *)&xaux_class,
			   gWindow);
  if (xaux_result  == False)
    return(False);

  return(True);
}

/* 
   Note:
   xaux_ext_Start(), xaux_ext_Draw(), xaux_ext_Done() 
   These three functions are all called by xaux_ext_process_client_message()

   xaux_ext_SetValue() will send auxiliary window information to language engine;
*/

/* Method - Start */
Bool
xaux_ext_Start (xaux_class_t *xc, aux_ext_data_t *aux_ext_data)
{
  char *locale = NULL;
  int  locale_id = 0;
#if 0
  int i = 1;
  while (i);
#endif
  
  KOLE_LOG (LOGDEST_STDOUT,
	    "xaux_ext_Start: im:%d, ic:%d",
	    aux_ext_data->im, aux_ext_data->ic);
  
  im_ = aux_ext_data->im;
  ic_ = aux_ext_data->ic;
  xc_ = xc;
  
  p_engine_property = leproperty_init ();
  
  /* inform Language Engine that PaletteAux has started. */
  locale = (char *) getenv("LANG");
  if (locale != NULL) {
    locale_id = 0;
    PaletteAux_Connect_To_LE_Request(locale_id);
  } else
    PaletteAux_Connect_To_LE_Request(locale_id);
    
  return True;
}

/* Method - Draw */
Bool
xaux_ext_Draw (xaux_class_t *xc, aux_ext_data_t *aux_ext_data)
{
  KOLE_LOG (LOGDEST_STDOUT, "ext_Draw == im:0x%x, ic:0x%x\n",aux_ext_data->im, aux_ext_data->ic);
  im_ = aux_ext_data->im;
  ic_ = aux_ext_data->ic;
  xc_ = xc;

  paletteaux_notification_handler (aux_ext_data);
  return True;
}

/* Method - Done */
Bool xaux_ext_Done(xaux_class_t *xc, aux_ext_data_t *aux_ext_data)
{
  KOLE_LOG (LOGDEST_STDOUT,
	    "ext_Done im:0x%x, ic_id:0x%x",
	    aux_ext_data->im, aux_ext_data->ic);
  leproperty_done (p_engine_property);
  
  return True;
}


/* ================================================================= */
/*       Process Notify information From Language Engine             */
/* ================================================================= */
static void
paletteaux_notification_handler (aux_ext_data_t *aux_ext_data)
{
  int nIntegerCount, notification_type;

  nIntegerCount = aux_ext_data->integer_count;
  if (nIntegerCount <= 0) return;

  notification_type = aux_ext_data->integer_list[0];

  switch (notification_type)
    {
    case PALETTEAUX_SWITCH_INPUT_MODE_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_SWITCH_CONVERSION_NOTIFY Notify Received\n");
      palette_process_le_message_switch_conversion (aux_ext_data);
      break;
      /* I wouldn't need this */
    case PALETTEAUX_SWITCH_CONVERSION_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_SWITCH_CONVERSION_NOTIFY Notify Received\n");
      palette_process_le_message_switch_conversion (aux_ext_data);
      break;
      
      /*
	case PALETTEAUX_SWITCH_IME_NOTIFY:
	KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_SWITCH_IME_NOTIFY Notify Received\n");
	PaletteAux_Proc_LE_Switch_IME_Notify(aux_ext_data);
	break;
      */
    case PALETTEAUX_SWITCH_QJBJ_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_SWITCH_QJBJ_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_Switch_QjBj_Notify(aux_ext_data);
      break;
      
    case PALETTEAUX_SWITCH_PUNCT_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_SWITCH_PUNCT_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_Switch_Punct_Notify(aux_ext_data);
      break;
      /*
	case PALETTEAUX_UPDATE_IMEINFO_NOTIFY:
	KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_UPDATE_IMEINFO Notify Received\n");
	PaletteAux_Proc_LE_Update_IMEInfo_Notify(aux_ext_data);
	break;
      */
    case COMMONAUX_CHANGE_FOCUS_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "COMMONAUX_CHANGE_FOCUS_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_Change_Focus_Notify(aux_ext_data);
      break;
    case COMMONAUX_SET_IME_NEW_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "COMMONAUX_SET_IME_NEW_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_New_IMEInfo_Notify(aux_ext_data);
      break;
    case COMMONAUX_SET_IME_INFO_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "COMMONAUX_SET_IMEINFO Notify Received");
      PaletteAux_Proc_LE_Set_IMEInfo_Notify(aux_ext_data);
      break;
    case KOLE_AUX_SESSION_PROPERTY:
      paletteaux_set_session_property (aux_ext_data);
      break;
      
    case COMMONAUX_SET_IME_END_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "COMMONAUX_SET_IME_END_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_Set_IMEInfo_End_Notify(aux_ext_data);
      break;
    case COMMONAUX_UPDATE_KEYMAPINFO_NOTIFY:
      KOLE_LOG (LOGDEST_STDOUT, "PALETTEAUX_UPDATE_KEYMAPINFO_NOTIFY Notify Received\n");
      PaletteAux_Proc_LE_Update_KeymapInfo_Notify(aux_ext_data);
      break;
    }
}

static void
PaletteAux_Set_Selection_Owner ()
{
  Atom aux_atom =
    XInternAtom (gDisplay,
		 "CH_PALETTEAUX_MODULE_ATOM", False);
  XSetSelectionOwner(gDisplay, aux_atom, gWindow, CurrentTime);
}

void PaletteAux_Proc_LE_New_IMEInfo_Notify(aux_ext_data_t *aux_ext_data)
{
  /*
    IMEList_Free();
  */
}

void
paletteaux_set_session_property (aux_ext_data_t *aux_ext_data)
{
  int n_integer_count;
  n_integer_count = aux_ext_data->integer_count;
  if (n_integer_count <= 0) return;

  if (p_engine_property ||
      !( p_engine_property = leproperty_init () )) {
      KOLE_LOG (LOGDEST_STDOUT, "Critical Error");
      return;
  }
  
  leproperty_set_input_mode (p_engine_property, aux_ext_data->integer_list[1]);
  leproperty_set_keyboard (p_engine_property, aux_ext_data->integer_list[2]);
  leproperty_set_charset (p_engine_property, aux_ext_data->integer_list[3]);
  leproperty_set_deletion (p_engine_property, aux_ext_data->integer_list[4]);
  leproperty_set_commit (p_engine_property, aux_ext_data->integer_list[5]);
  
  paletteaux_update_display (p_engine_property);
}



void
PaletteAux_Proc_LE_Set_IMEInfo_Notify (aux_ext_data_t *aux_ext_data)
{
  IMEBaseRec baseinfo;
  int i, nIntegerCount, engine_num;

  nIntegerCount = aux_ext_data->integer_count;
  if (nIntegerCount <= 0) return;

  KOLE_LOG (LOGDEST_STDOUT, "PaletteAux_Proc_LE_Set_IMEInfo_Notify\n");

  baseinfo.engine_id = aux_ext_data->integer_list[1];
  baseinfo.locale_id = aux_ext_data->integer_list[2];
  baseinfo.encode_id = aux_ext_data->integer_list[3];
  baseinfo.status = aux_ext_data->integer_list[4];

  baseinfo.ename = (char *)(aux_ext_data->string_list[0].ptr);
  baseinfo.kname = (char *)(aux_ext_data->string_list[1].ptr);
  /*
    Add_IME_To_AllList(&baseinfo);
  */
}

void PaletteAux_Proc_LE_Set_IMEInfo_End_Notify(aux_ext_data_t *aux_ext_data)
{
#if 0
  /* process user defined imes, such as user prefer IMEs*/
  Select_IMEs_From_Profile();

  /* create IME list menu */

  PaletteAux_CreateIMEListMenu();
#endif
}

void PaletteAux_Proc_LE_Update_IMEInfo_Notify(aux_ext_data_t *aux_ext_data)
{
#if 0
  /* process user defined imes, such as user prefer IMEs*/
  Select_IMEs_From_Profile ();

  /* create IME list menu */

  PaletteAux_CreateIMEListMenu();
#endif

}

void PaletteAux_Proc_LE_Update_KeymapInfo_Notify(aux_ext_data_t *aux_ext_data)
{
  /*
    int i, engine_id, ime_id;

    engine_id = aux_ext_data->integer_list[1];

    if (IMEVKB_Check_If_Exist(engine_id)) return;

    ime_id = get_ime_id_by_engine_id(&AllIMEList, engine_id);
    if (ime_id == -1) return;

    IMEVKB_Name_List_Add(engine_id, AllIMEList.arrIME_Base[ime_id]->kname);
  */
}

void
palette_process_le_message_switch_conversion (aux_ext_data_t *aux_ext_data)
{
  int on_status;
  INPUT_MODE_T new_mode  =  aux_ext_data->integer_list[1];
  gboolean visibility;

  leproperty_set_input_mode (p_engine_property, aux_ext_data->integer_list[1]);
  visibility = new_mode == INPUT_MODE_ENGLISH ? FALSE : TRUE;

  paletteaux_update_display (p_engine_property);
  paletteaux_change_visibility (visibility);

}

/* if find item by engine_id, return its index, else return -1 */
int get_ime_id_by_engine_id(IMEListRec *imelist, int engine_id)
{
  int i;

  for (i = 0; i < imelist->nIME_Num; i++) {
    if (imelist->arrIME_Base[i] && 
	imelist->arrIME_Base[i]->engine_id == engine_id) 
      return(i);
  }
  return(-1);
}

void
PaletteAux_Proc_LE_Switch_IME_Notify (aux_ext_data_t *aux_ext_data)
{
#if 0
  
  int switch_type;
  int engine_id, ime_id, nIME_Num;
	
  switch_type = aux_ext_data->integer_list[1];
  /*
    nIME_Num = SelectedIMEList.nIME_Num;
  */
  KOLE_LOG (LOGDEST_STDOUT, "SelectedIMEList.nIME_Num:%d\n", nIME_Num);
  if (nIME_Num <= 0) return;

  switch(switch_type)
    {
    case IME_ROUND_SWITCH:
      /* select next available IME */
      /*
	engine_id = gPAData.engine_id;
      */
      engine_id = 0;
      ime_id = get_ime_id_by_engine_id(&SelectedIMEList, engine_id);
      KOLE_LOG (LOGDEST_STDOUT, "IME_ROUND_SWITCH == current ime_id:%d\n", ime_id);
      ime_id = (ime_id + 1) % nIME_Num;
      break;	

    case IME_SELECT_SWITCH:
      /* select a specific available IME */
      ime_id = aux_ext_data->integer_list[2];
      KOLE_LOG (LOGDEST_STDOUT, "IME_SELECT_SWITCH == ime_no:%d\n", ime_id);
      break;	
    }

  KOLE_LOG (LOGDEST_STDOUT, "IME_SWITCH == ime_id:%d\n", ime_id);

  /* Change IME logo on the control bar */
  /* and need notify LE to switch IME */
  /*
    PaletteAux_ChangeIME(ime_id, True);
  */
#endif
}

void PaletteAux_Proc_LE_Switch_QjBj_Notify(aux_ext_data_t *aux_ext_data)
{
  /* Change auxiliary window Full_Width/half_Width information */
#if 0
  ui_toggle_letter (aux_ext_data->integer_list[1]);
#endif
}

void PaletteAux_Proc_LE_Switch_Punct_Notify(aux_ext_data_t *aux_ext_data)
{
  /* Change auxiliary window English/Chinese Punctuation information */
#if 0
  ui_toggle_punct (aux_ext_data->integer_list[1]);
#endif
}

void
PaletteAux_Proc_LE_Change_Focus_Notify (aux_ext_data_t *aux_ext_data)
{
  int pos_x, pos_y;
  int toolbar_window_show_status;
  gboolean full_width_letter_status, full_width_punct_status;
  int engine_id;
  INPUT_MODE_T input_mode;
  
  OPTION_KEYBOARD_LAYOUT kbd;
  OPTION_CHARSET charset;
  OPTION_DELETION deletion;
  OPTION_COMMIT_MODE commit;

  pos_x 	= aux_ext_data->integer_list[1];
  pos_y 	= aux_ext_data->integer_list[2];
  toolbar_window_show_status 	= aux_ext_data->integer_list[3];
  full_width_letter_status 	= aux_ext_data->integer_list[4];
  full_width_punct_status 	= aux_ext_data->integer_list[5];
  engine_id 	= aux_ext_data->integer_list[6];
  input_mode = aux_ext_data->integer_list[7];
  kbd = aux_ext_data->integer_list[8];
  charset = aux_ext_data->integer_list[9];
  deletion  = aux_ext_data->integer_list[10];
  commit = aux_ext_data->integer_list[11];

  leproperty_set_keyboard (p_engine_property, kbd);
  leproperty_set_charset (p_engine_property, charset);
  leproperty_set_deletion (p_engine_property, deletion);
  leproperty_set_commit (p_engine_property, commit);
  
#ifdef EVIL
#endif  

  if (toolbar_window_show_status)
    PaletteAux_Set_Selection_Owner();

  if (input_mode == INPUT_MODE_NONE ||input_mode == INPUT_MODE_ENGLISH){
    
    paletteaux_change_visibility (FALSE);
    
  } else {
    
    gtk_window_get_position (palettecore.ppalette, pos_x, pos_y);
#if 0
    ui_toggle_letter (full_width_letter_status);
    ui_toggle_punct (full_width_punct_status);
#endif
    paletteaux_update_display (p_engine_property);
    
  }
}

/* ================================================================= */
/*             Send information to Language Engine                   */
/* ================================================================= */
void
PaletteAux_Connect_To_LE_Request (int locale_id)
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_CONNECT;
  pIntegerList[1] = locale_id;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Switch_LE_Conversion_Request(int on)
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  /* Fix Me */
  pIntegerList[0] = PALETTEAUX_SWITCH_CONVERSION_NOTIFY;
  pIntegerList[1] = on;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Switch_LE_Engine_Request(int engine_id)
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_SWITCH_IME;
  pIntegerList[1] = engine_id;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void
paletteaux_send_switch_charset_request (int charset)
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_SWITCH_CHARSET_NOTIFY;
  pIntegerList[1] = charset;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Switch_LE_QjBj_Request(int qjbj)
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_SWITCH_QJBJ;
  pIntegerList[1] = qjbj;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

/*
  void PaletteAux_Switch_LE_Punct_Request(int punct)
  {
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_SWITCH_PUNCT;
  pIntegerList[1] = punct;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
  }
*/
void PaletteAux_Change_LE_Position_Request(int x, int y)
{
  int nIntegerCount, pIntegerList[3];

  nIntegerCount = 3;
  pIntegerList[0] = PALETTEAUX_CHANGE_POSITION;
  pIntegerList[1] = x;
  pIntegerList[2] = y;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Show_SelectAux_Request()
{
  int nIntegerCount, pIntegerList[1];

  nIntegerCount = 1;
  pIntegerList[0] = PALETTEAUX_SHOW_SELECTAUX;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Show_OptionAux_Request()
{
  int nIntegerCount, pIntegerList[1];

  nIntegerCount = 1;
  pIntegerList[0] = PALETTEAUX_SHOW_OPTIONAUX;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void
paletteaux_send_show_keyboardaux_request (int n_keyboard_id)
#if 0
PaletteAux_Show_KeyboardAux_Request (int nKeyboardID)
#endif
{
  int nIntegerCount, pIntegerList[2];

  nIntegerCount = 2;
  pIntegerList[0] = PALETTEAUX_SHOW_KEYBOARDAUX;
  pIntegerList[1] = n_keyboard_id;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Show_LookupAux_Request()
{
  int nIntegerCount, pIntegerList[1];

  nIntegerCount = 1;
  pIntegerList[0] = PALETTEAUX_SHOW_LOOKUPAUX;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_StartAction_Request(char *command)
{
  int nIntegerCount, pIntegerList[1];
  int nStringCount, pStringLen[1];
  char *pStringList[1];

  nIntegerCount = 1;
  pIntegerList[0] = PALETTEAUX_START_ACTION;
  nStringCount = 1;
  pStringLen[0] = strlen(command);
  pStringList[0] = command;
  NotifyStringListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList,
				       nStringCount, pStringLen,
				       pStringList);

}

void PaletteAux_Lost_Focus_Request()
{
  int nIntegerCount, pIntegerList[1];

  nIntegerCount = 1;
  pIntegerList[0] = COMMONAUX_LOST_FOCUS;
  NotifyIntegerListDataToLanguageEngine(gDisplay, nIntegerCount, pIntegerList);
}

void PaletteAux_Set_Options_Request()
{
  /*
    int nIntegerCount, pIntegerList[MAX_ENGINE_NUM + 1];
    int nStringCount, pStringLen[MAX_ENGINE_NUM];
    char *pStringList[MAX_ENGINE_NUM], *name;
    int i, nNum;

    if (gIMEOptionsNum <= 0) return;

    nNum = gIMEOptionsNum;
    if (nNum > MAX_ENGINE_NUM) nNum = MAX_ENGINE_NUM;

    nIntegerCount = nNum + 1;
    pIntegerList[0] = COMMONAUX_UPDATE_OPTIONSINFO;

    nStringCount = nNum;
    for (i=0; i<nNum; i++) {
    name = gIMEOptions[i]->ime_ename;
    pStringLen[i] = strlen(name);
    pStringList[i] = name;
    pIntegerList[i + 1] = gIMEOptions[i]->opt_value;
    }
    NotifyStringListDataToLanguageEngine(GDK_DISPLAY(), nIntegerCount, pIntegerList,
    nStringCount, pStringLen,
  */
}

NotifyIntegerListDataToLanguageEngine(Display *display, 
				      int nIntegerCount, int *pIntegerList)
{
  aux_ext_data_t aux_ext_data;

  KOLE_LOG (LOGDEST_STDOUT,
	    "NotifyIntegerListDataToLanguageEngine(im_:%d, ic_:%d)",
	    im_, ic_);
  
#if 0
  /* This is really hack */
  if (!im_ || !ic_ || !xc_)
    return;
#endif
  
  aux_ext_data.im = im_;
  aux_ext_data.ic = ic_;
  aux_ext_data.integer_count = nIntegerCount;
  aux_ext_data.integer_list = pIntegerList;
  aux_ext_data.string_count = 0;
  aux_ext_data.string_list = NULL;
  aux_ext_data.string_ptr = NULL;
  aux_ext_data.point.x = 0;
  aux_ext_data.point.y = 0;

  xaux_ext_SetValue(display, xc_, &aux_ext_data);
  XFlush(display);
}

NotifyStringListDataToLanguageEngine(Display *display, 
				     int nIntegerCount, int *pIntegerList,
				     int nStringCount,  int *pStringLen,
				     char **pStringList)
{
  int i;

  aux_ext_data_t aux_ext_data;
  aux_ext_string_t *p;
  
  KOLE_LOG (LOGDEST_STDOUT,
	    "NotifyIntegerListDataToLanguageEngine(im_:%d, ic_:%d)",
	    im_, ic_);
  
#if 0
  /* This is really hack */
  if (!im_ || !ic_ || !xc_)
    return;
#endif

  aux_ext_data.im = im_;
  aux_ext_data.ic = ic_;
  aux_ext_data.integer_count = nIntegerCount;
  aux_ext_data.integer_list = pIntegerList;
  aux_ext_data.point.x = 0;
  aux_ext_data.point.y = 0;

  aux_ext_data.string_count = nStringCount;
  aux_ext_data.string_ptr = NULL;

  if (nStringCount > 0) {
    aux_ext_data.string_list = (aux_ext_string_t *) calloc(nStringCount, sizeof(aux_ext_string_t));
    for (i = 0; i < nStringCount; i++) {
      aux_ext_string_t *p = &aux_ext_data.string_list[i];
      p->length = pStringLen[i];
      p->ptr = (unsigned char *) (pStringList[i]);
    }
  }

  xaux_ext_SetValue(display, xc_, &aux_ext_data);
  XFlush(display);

  free(aux_ext_data.string_list);
}
