diff Xwnmo/xwnmo/ximdispt.c @ 0:bbc77ca4def5

initial import
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Thu, 13 Dec 2007 04:30:14 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Xwnmo/xwnmo/ximdispt.c	Thu Dec 13 04:30:14 2007 +0900
@@ -0,0 +1,4609 @@
+/*
+ * $Id: ximdispt.c,v 1.2 2001/06/14 18:16:18 ura Exp $
+ */
+
+/*
+ * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
+ * This file is part of FreeWnn.
+ * 
+ * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
+ *
+ * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Emacs; see the file COPYING.  If not, write to the
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Commentary:
+ *
+ * Change log:
+ *
+ * Last modified date: 8,Feb.1999
+ *
+ * Code:
+ *
+ */
+
+/*
+ *    Author Name         : Li Yuhong
+ *    File Name           : XimDispt.c
+ *    Module Description  : This module is to be corresponding to all
+ *                          protocol requests of X11R6 IM Version 1.0.
+ *    Modification History: 
+ *      Jul 1, 1994       : initial version.
+ */
+#ifndef X11R5
+#include <stdio.h>
+#include <X11/Xlib.h>
+#ifndef NEED_EVENTS
+#define NEED_EVENTS
+#include <X11/Xproto.h>         /* for xEvent */
+#undef NEED_EVENTS
+#endif /* !NEED_EVENTS */
+#include "XIMproto.h"           /* for ximICValuesReq... */
+#include "Ximprot.h"
+#include "sdefine.h"
+#include "xim.h"
+#include "sheader.h"
+#include "ext.h"
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Definition of Constant                     *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+/*
+ * name of "@im" modifier, which is compatible with R5.  The reasonable name
+ * might be "xwnmo".
+ */
+#define XIM_SERVER_NAME         "_XWNMO"
+
+#define BASE_IM_ID              0       /* valid XIMID > 0 */
+#define BUFFER_MAX              128
+
+#define ICPreeditAttributes     28      /* ic attr id. */
+#define ICStatusAttributes      29
+#define ICSeparatorOfNestedList 30
+
+#define XIM_EXT_SET_EVENT_MASK  128     /* extension must be >= 128 */
+#if defined(EXT_MOVE) || defined(SPOT)  /* SPOT is name in Xsi R5 */
+#define XIM_EXT_MOVE            130
+#endif /* defined(EXT_MOVE) || defined(SPOT) */
+
+#define NO_NEST                 (XIMAttrList)NULL
+#define END_OF_XIMATTRLIST      {0, 0, (char *)NULL, ((XIMAttrList)NULL)}
+
+#define XIMNoString             (1L)
+#define XIMNoFeedback           (2L)
+
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Definition of Local Data Type              *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+#define PIXMAP  CARD32          /* for CALLBACKS only */
+
+/*
+ * XIM attribute structure for both IM and IC value.
+ */
+typedef struct _XIMAttrRec
+{
+  CARD16 attr_id;               /* attr id */
+  CARD16 type;                  /* type of attr */
+  char *name;                   /* name of attr */
+  struct _XIMAttrRec *nest;     /* nested list */
+}
+XIMAttrRec, *XIMAttrList;
+
+/*
+ * XIM client structure connected to this server.
+ */
+typedef struct _XIMContextRec
+{
+  XIMID im_id;                  /* IM id */
+  struct _XIMContextRec *next;  /* next of client */
+}
+XIMContextRec, *XIMContextList;
+
+/*
+ * extension.
+ */
+typedef struct
+{
+  char *name;                   /* ext name */
+  CARD8 major_code;             /* ext major opcode */
+  CARD8 minor_code;             /* ext minor opcode */
+}
+XIMQueryExtRec;
+
+#ifdef DYNAMIC_EVENT_FLOW_MODEL
+/*
+ * just example for Dynamic Event Flow Model.
+ */
+typedef struct
+{
+  KeySym key;
+  KeySym modifier;
+  unsinged long modifier_mask;
+}
+TriggerKeysRec, *TriggerKeysList;
+
+static TriggerKeyRec trigger_keys_list[] = {
+  {XK_backslash, XK_Control_L, ControlMask}
+}
+#endif                          /* DYNAMIC_EVENT_FLOW_MODEL */
+
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Definition of Macro                        *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+/*
+ * assign a unique id.
+ */
+#define ALLOC_ID(n)             (++n)
+
+/*
+ * shared CT string buffer.
+ */
+#define GET_SHARED_CT_BUFFER()                  (ct_buf)
+
+/*
+ * swap data of protocol.
+ */
+#define GET_CARD16(s)           \
+        ((CARD16)((need_byteswap() == True)? byteswap_s(s): s))
+#define GET_CARD32(s)           \
+        ((CARD32)((need_byteswap() == True)? byteswap_l(s): s))
+
+/*
+ * Pad(n) for protocol data on 4-byte word boundory.
+ */
+#define PAD(n)                  ((4 - (n) % 4) % 4)
+
+/*
+ * pre-make memory for frequent allocation of Request/Reply protocol data.
+ */
+#define MALLOC_REQUEST(n)       \
+        (((n) > (sizeof buffer_request))? (CARD8 *)Malloc(n): &buffer_request[0])
+#define MALLOC_REPLY(n)         \
+        (((n) > (sizeof buffer_reply))? (CARD8 *)Malloc(n): &buffer_reply[0])
+#define FREE(p)                 \
+        {if ((p) != &buffer_request[0] && (p) != &buffer_reply[0]) XFree(p);}
+
+#define XIM_SERIALNUMBER(serial)  \
+                (CARD16)(((unsigned long)serial >> 16) & 0xffff)
+#define XIM_SET_SERIALNUMBER(serial)    \
+        (((unsigned long)serial & 0xffff) << 16)
+
+#define LENGTH_KEYSYM(f, k)     \
+        (((f)&XimLookupKeySym)? (sizeof(CARD16)+k): 0)
+#define LENGTH_STRING_WITH_FLAG(f, n)   \
+        (((f)&XimLookupChars)? (sizeof(CARD16)+n+PAD(n)): 0)
+
+#define LENGTH_STRING(n)        ((n > 0) ?                                  \
+         (sizeof(CARD16) +                      /* 2 n string length */     \
+          n +                                   /* n string */              \
+          PAD(sizeof(CARD16) + n)): 0)  /* p Pad(2 + n) */
+#define LENGTH_FEEDBACK(n)      ((n > 0)?                                   \
+         (sizeof(CARD16) +                      /* 2 m byte length */       \
+          sizeof(CARD16) +                      /* 2 unused */              \
+          sizeof(CARD32) * n): 0)       /* m LISTofXIMFEEDBACK */
+
+#define CUR_IM_ID()             (cur_x->im_id)
+#define CUR_IC_ID()             (cur_x->number)
+#define CUR_CLIENT_EVENT()      ((XEvent *)&(cur_x->cur_event))
+
+#define LENGTH_TEXT(t, sl, fn)  ((t == XIMTextType)?                        \
+        (LENGTH_STRING(sl) + LENGTH_FEEDBACK(fn)): 0)
+#define LENGTH_PIXMAP(t)        ((t != XIMTextType)? sizeof(PIXMAP): 0)
+
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Definition of Local Variable               *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+static CARD8 buffer_request[BUFSIZ];    /* for protocol request */
+static CARD8 buffer_reply[BUFSIZ];      /* for protocol reply */
+
+/*
+ * X selection atom, target and property in pre-connection.
+ */
+static Atom transport_target;
+                                        /* atom name of TRANSPORT target */
+static Atom locale_target;      /* atom name of LOCALE target */
+static unsigned char *transport_prop;
+                                        /* string prop of TRANSPORT target */
+static unsigned char *locale_prop;      /* string prop of LOCALE target */
+
+/*
+ * comma-separated list of locales supported by this server.
+ */
+static unsigned char *locale_supported;
+
+static XIMContextList ximlist;  /* list of comming IM client */
+static int cur_status;          /* current protol status */
+static XIMID cur_im_id;         /* current client IM id */
+static XICID cur_ic_id;         /* current client IC id */
+static char cur_use_lang[BUFFER_MAX];
+                                        /* current lang from XIM_OPEN */
+
+/*
+ * list of IM attributes.
+ */
+static XIMAttrRec im_attr[] = {
+  {ICInputStyle, XimType_XIMStyles, XNQueryInputStyle, NO_NEST},
+  END_OF_XIMATTRLIST
+};
+
+/*
+ * list of IC preedit attributes. 
+ */
+static XIMAttrRec ic_attr_pre_area[] = {
+  {ICArea, XimType_XRectangle, XNArea, NO_NEST},
+  {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
+  {ICSpotLocation, XimType_XPoint, XNSpotLocation, NO_NEST},
+  {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
+  {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
+  {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
+  {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
+  {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
+  {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
+  {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
+  {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
+  {ICSeparatorOfNestedList,
+   XimType_SeparatorOfNestedList,
+   XNSeparatorofNestedList, NO_NEST},
+  END_OF_XIMATTRLIST
+};
+
+/*
+ * list of IC status attributes.
+ */
+static XIMAttrRec ic_attr_sts_area[] = {
+  {ICArea, XimType_XRectangle, XNArea, NO_NEST},
+  {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
+  {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
+  {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
+  {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
+  {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
+  {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
+  {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
+  {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
+  {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
+  {ICSeparatorOfNestedList,
+   XimType_SeparatorOfNestedList,
+   XNSeparatorofNestedList, NO_NEST},
+  END_OF_XIMATTRLIST
+};
+
+/*
+ * list of IC attributes.
+ */
+static XIMAttrRec ic_attr[] = {
+  {ICInputStyle, XimType_CARD32, XNInputStyle, NO_NEST},
+  {ICClientWindow, XimType_Window, XNClientWindow, NO_NEST},
+  {ICFocusWindow, XimType_Window, XNFocusWindow, NO_NEST},
+  {ICFilterEvents, XimType_CARD32, XNFilterEvents, NO_NEST},
+  {ICPreeditAttributes, XimType_NEST, XNPreeditAttributes, ic_attr_pre_area},
+  {ICStatusAttributes, XimType_NEST, XNStatusAttributes, ic_attr_sts_area},
+  END_OF_XIMATTRLIST
+};
+
+/*
+ * list of extension supported.
+ */
+static XIMQueryExtRec extension_list[] = {
+  {"XIM_EXT_SET_EVENT_MASK", XIM_EXT_SET_EVENT_MASK, 0},
+#if defined(EXT_MOVE) || defined(SPOT)
+  {"XIM_EXT_MOVE", XIM_EXT_MOVE, 0}
+#endif /* defined(EXT_MOVE) || defined(SPOT) */
+};
+
+static CARD8 imattr_list[BUFSIZ];       /* packed im_attr list */
+static CARD8 icattr_list[BUFSIZ];       /* packed ic_attr list */
+static INT16 imattr_list_size;  /* byte length */
+static INT16 icattr_list_size;  /* byte length */
+
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *               Declaration of Extenal Variable and Function         *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+extern XIMCmblk *cur_cblk;      /* current client block */
+
+extern int XmuGetHostname ();   /* in SysUtil.h of Xmu */
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *               Definition of Public Variable and Function           *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+Atom server_id;                 /* atom name of this server "@im" */
+
+int xim_send_nofilter ();       /* used before its definition. */
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Private Functions                          *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+/*
+ *    Function Name : _WriteToClientFlush()
+ *    Description   : write data to client immediately with flush action.
+ *                    same as do_socket.c: _WriteToClient() if no flush.
+ *    Parameter     :
+ *      p           : pointer to data.
+ *      num         : byte length of data.
+ *    Returned Value:
+ *        >= 0      : byte length of data written to client.
+ *        < 0       : error in writing.
+ */
+static int
+_WriteToClientFlush (p, num)
+     char *p;
+     int num;
+{
+  int ret;
+
+  if ((ret = _WriteToClient (p, num)) >= 0)
+    {
+      if (_Send_Flush () == 0)
+        return ret;             /* success */
+    }
+  return ret;
+}
+
+/*
+ *    Function Name : _XimWireToEvent()
+ *    Description   : convert xEvent to XEvent, modified from Xlibint.c:
+ *                    _XWireToEvent().
+ *    Parameter     :
+ *      dpy         : pointer to X display.
+ *      serial      : serial number of event.
+ *      event       : pointer to data of X protocol xEvent
+ *      re          : pointer to data of XEvent, returned.
+ *    Returned Value:
+ *      True        : conversion is successful.
+ *      False       : error.
+ */
+static Bool
+_XimWireToEvent (dpy, serial, event, re)
+     register Display *dpy;     /* pointer to display structure */
+     register int serial;       /* serial number of event */
+     register xEvent *event;    /* wire protocol event */
+     register XEvent *re;       /* pointer to where event should be reformatted */
+{
+
+  re->type = event->u.u.type & 0x7f;
+  ((XAnyEvent *) re)->serial = XIM_SET_SERIALNUMBER (serial);
+  ((XAnyEvent *) re)->send_event = ((event->u.u.type & 0x80) != 0);
+  ((XAnyEvent *) re)->display = dpy;
+
+  /* Ignore the leading bit of the event type since it is set when a
+     client sends an event rather than the server. */
+
+  switch (event->u.u.type & 0177)
+    {
+    case KeyPress:
+    case KeyRelease:
+      {
+        register XKeyEvent *ev = (XKeyEvent *) re;
+        ev->root = event->u.keyButtonPointer.root;
+        ev->window = event->u.keyButtonPointer.event;
+        ev->subwindow = event->u.keyButtonPointer.child;
+        ev->time = event->u.keyButtonPointer.time;
+        ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
+        ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
+        ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
+        ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
+        ev->state = event->u.keyButtonPointer.state;
+        ev->same_screen = event->u.keyButtonPointer.sameScreen;
+        ev->keycode = event->u.u.detail;
+      }
+      break;
+    case ButtonPress:
+    case ButtonRelease:
+      {
+        register XButtonEvent *ev = (XButtonEvent *) re;
+        ev->root = event->u.keyButtonPointer.root;
+        ev->window = event->u.keyButtonPointer.event;
+        ev->subwindow = event->u.keyButtonPointer.child;
+        ev->time = event->u.keyButtonPointer.time;
+        ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
+        ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
+        ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
+        ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
+        ev->state = event->u.keyButtonPointer.state;
+        ev->same_screen = event->u.keyButtonPointer.sameScreen;
+        ev->button = event->u.u.detail;
+      }
+      break;
+    default:
+      return False;
+    }
+  return True;
+}
+
+/*
+ *    Function Name : _XimEventToWire()
+ *    Description   : convert XEvent to xEvent, modified from EvToWire.c:
+ *                    _XEventToWire().
+ *    Parameter     :
+ *      re          : pointer to data of XEvent.
+ *      event       : pointer to data of X protocol xEvent, returned
+ *    Returned Value:
+ *      True        : conversion is successful.
+ *      False       : error.
+ */
+static Bool
+_XimEventToWire (re, event)
+     register XEvent *re;       /* pointer to where event should be reformatted */
+     register xEvent *event;    /* wire protocol event */
+{
+  switch (event->u.u.type = re->type)
+    {
+    case KeyPress:
+    case KeyRelease:
+      {
+        register XKeyEvent *ev = (XKeyEvent *) re;
+        event->u.keyButtonPointer.root = ev->root;
+        event->u.keyButtonPointer.event = ev->window;
+        event->u.keyButtonPointer.child = ev->subwindow;
+        event->u.keyButtonPointer.time = ev->time;
+        event->u.keyButtonPointer.eventX = ev->x;
+        event->u.keyButtonPointer.eventY = ev->y;
+        event->u.keyButtonPointer.rootX = ev->x_root;
+        event->u.keyButtonPointer.rootY = ev->y_root;
+        event->u.keyButtonPointer.state = ev->state;
+        event->u.keyButtonPointer.sameScreen = ev->same_screen;
+        event->u.u.detail = ev->keycode;
+      }
+      break;
+    case ButtonPress:
+    case ButtonRelease:
+      {
+        register XButtonEvent *ev = (XButtonEvent *) re;
+        event->u.keyButtonPointer.root = ev->root;
+        event->u.keyButtonPointer.event = ev->window;
+        event->u.keyButtonPointer.child = ev->subwindow;
+        event->u.keyButtonPointer.time = ev->time;
+        event->u.keyButtonPointer.eventX = ev->x;
+        event->u.keyButtonPointer.eventY = ev->y;
+        event->u.keyButtonPointer.rootX = ev->x_root;
+        event->u.keyButtonPointer.rootY = ev->y_root;
+        event->u.keyButtonPointer.state = ev->state;
+        event->u.keyButtonPointer.sameScreen = ev->same_screen;
+        event->u.u.detail = ev->button;
+      }
+      break;
+    default:
+      return False;
+    }
+  return True;
+}
+
+/*
+ * get list of locale names as the format:
+ *            "locale_1,locale_2,...,locale_n"
+ * and return the length of the string above.
+ */
+static char *
+GetLocaleSupported ()
+{
+  return (!xim->supported_language) ? "C" : xim->supported_language;
+}
+
+/*
+ *    Function Name : _CheckLocaleName()
+ *    Description   : check if the client locale is supported in this server.
+ *    Parameter     :
+ *      buf         : string buffer of client locale.
+ *      loc_name    : comma-separated list of locales supported in this server.
+ *    Returned Value:
+ *      True        : it is supported.
+ *      False       : not supproted.
+ */
+static Bool
+_CheckLocaleName (buf, loc_name)
+     CARD8 *buf;
+     char *loc_name;
+{
+  int str_len = (int) buf[0];
+  int len;
+  char *ptr = (char *) locale_supported;
+  char *str = (char *) &buf[1];
+  register char *p;
+
+  loc_name[0] = '\0';
+  for (;;)
+    {
+      for (p = ptr; ((*p != ',') && (*p)); p++);
+      len = (int) (p - ptr);
+      if ((str_len == len) && (!strncmp (str, ptr, len)))
+        {
+          (void) strncpy (loc_name, str, len);
+          loc_name[len] = '\0';
+          return True;
+        }
+      if (!(*p))
+        break;
+      ptr = p + 1;
+    }
+  return False;
+}
+
+/*
+ *    Function Name : GetIMWithId()
+ *    Description   : search a client context with IM id.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *    Returned Value:
+ *      XIMContextRec *
+ *                  : pointer to the client context found.
+ *      NULL        : not found.
+ */
+static XIMContextRec *
+GetIMWithId (im_id)
+     register XIMID im_id;
+{
+  register XIMContextRec *im;
+
+  for (im = ximlist; im; im = im->next)
+    {
+      if (im->im_id == im_id)
+        return im;
+    }
+  return (XIMContextRec *) NULL;
+}
+
+/*
+ *    Function Name : RemoveIMWithId()
+ *    Description   : remove a IM client context.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *    Returned Value:
+ *      True        : the IM client context with im_id is removed from list
+ *                    and is freed its memory.
+ *      False       : not found with this im_id.
+ */
+static Bool
+RemoveIMWithId (im_id)
+     XIMID im_id;
+{
+  register XIMContextRec *im, *pre_im;
+
+  for (im = pre_im = ximlist; im; pre_im = im, im = im->next)
+    {
+      if (im->im_id == im_id)
+        {
+          if (pre_im != im)
+            {
+              pre_im->next = im->next;
+            }
+          else
+            {
+              ximlist = im->next;
+            }
+          break;
+        }
+    }
+  if (!im)
+    return False;
+  XFree ((char *) im);
+  return True;
+}
+
+/*
+ *    Function Name : GetICWithId()
+ *    Description   : search a client structure with IC id.
+ *    Parameter     :
+ *      ic_id       : client input-context-id.
+ *    Returned Value:
+ *      XIMClientRec*
+ *                  : pointer to the client structure found.
+ *      NULL        : not found.
+ */
+static XIMClientRec *
+GetICWithId (ic_id)
+     register int ic_id;
+{
+  register XIMClientRec *xc;
+
+  for (xc = ximclient_list; xc != NULL; xc = xc->next)
+    {
+      if (xc->number == ic_id)
+        return xc;
+    }
+  return (XIMClientRec *) NULL;
+}
+
+/*
+ *    Function Name : AddHead()
+ *    Description   : fill head data to a protocol reply which will be
+ *                    sent to client.  The head data to be filed is as follows:
+ *                        CARD8  major_opcode
+ *                        CARD8  minor_opcode
+ *                        CARD16 data length in 4-byte word
+ *    Parameter     :
+ *      reply       : pointer to a protocol reply structure, which is 
+ *                    to be filled head data.
+ *      major_code  : major opcode of this protocol.
+ *      minor_code  : minor opcode of this protocol.
+ *      len         : data length of protocol except head.
+ *    Returned Value:
+ *      > 0         : byte length of head data, always XIM_HEADER_SIZE.
+ */
+static int
+AddHead (reply, major_code, minor_code, len)
+     CARD8 *reply;
+     CARD8 major_code;
+     CARD8 minor_code;
+     int len;
+{
+  CARD8 *buf_8 = reply;
+  CARD16 *buf_16 = (CARD16 *) (reply + sizeof (CARD8) * 2);
+
+  buf_8[0] = major_code;
+  buf_8[1] = minor_code;
+  buf_16[0] = GET_CARD16 (len / 4);
+  return XIM_HEADER_SIZE;
+}
+
+/*
+ *    Function Name : SetClientSync()
+ *    Description   : set the client to a sync flag.
+ *    Parameter     :
+ *      xc          : pointer to a client structure.
+ *      sync        : flag of sync.
+ *    Returned Value:
+ *      <none> 
+ */
+#ifdef NEED_FUNCTION
+
+static void
+SetClientSync (xc, sync)
+     XIMClientRec *xc;
+     Bool sync;
+{
+  xc->sync_needed = sync;
+}
+
+static Bool
+AllSyncDone (im_id, ic_id)
+     XIMID im_id;
+     XICID im_cd;
+{
+  return True;
+}
+
+static void
+SyncAll (im_id, ic_id)
+     XIMID im_id;
+     XICID im_cd;
+{
+}
+
+#else
+
+#define SetClientSync(xc, sync)                 ((xc)->sync_needed = sync)
+#define AllSyncDone(im_id, ic_id)               (True)
+#define SyncAll(im_id, ic_id)
+
+#endif /* NEED_FUNCTION */
+
+/*
+ *    Function Name : ClientSyncDone()
+ *    Description   : If this client has True flag needed to do sync, do it
+ *                    and turn off the sync flag (False).
+ *    Parameter     :
+ *      xc          : pointer to a client structure.
+ *    Returned Value:
+ *      True        : yes, sync has done.
+ *      False       : no sync.
+ */
+static Bool
+ClientSyncDone (xc)
+     XIMClientRec *xc;
+{
+  Bool sync_done;
+
+  sync_done = xc->sync_needed;
+  xc->sync_needed = False;
+  return sync_done;
+}
+
+/*
+ *    Function Name : GetAuth()
+ *    Description   : get names of authentification from IM library.
+ *    Parameter     :
+ *      list        : buffer list.
+ *      num         : number of list elements.
+ *      length      : byte length of buffer list.
+ *      names_returned
+ *                  : auth name returned.
+ *    Returned Value:
+ *      True        : successed.
+ *      False       : wrong auth name.
+ */
+
+ /*ARGSUSED*/ static Bool
+GetAuth (list, num, length, names_return)
+     CARD8 *list;
+     int num;
+     int length;
+     char *names_return;
+{
+  /* it is free authentification so far. */
+  return True;
+}
+
+/*
+ *    Function Name : CreateAttrList()
+ *    Description   : pack IM/IC attribute list to a compact data.
+ *    Parameter     :
+ *      table       : list of IM/IC attributes, end with the empty name.
+ *      list        : returned data that contains packed list of attribute.
+ *    Returned Value:
+ *      >= 0        : byte length of packed list.
+ */
+static int
+CreateAttrList (table, list)
+     XIMAttrList table;
+     CARD8 *list;
+{
+  CARD16 *buf_16;
+  INT16 total = 0;
+  int len, i;
+
+  for (i = 0; table[i].name; i++)
+    {
+      buf_16 = (CARD16 *) list;
+      len = strlen (table[i].name);
+      buf_16[0] = GET_CARD16 (table[i].attr_id);        /* 2 attr ID */
+      buf_16[1] = GET_CARD16 (table[i].type);   /* 2 type */
+      buf_16[2] = GET_CARD16 (len);     /* 2 length */
+      memcpy ((char *) &buf_16[3], table[i].name, len); /* n attr */
+      len = sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16) + len + PAD (len + 2);
+      list += len;
+      total += len;
+      if (table[i].nest)
+        {
+          len = CreateAttrList (table[i].nest, list);
+          list += len;
+          total += len;
+        }
+    }
+  return total;
+}
+
+/*
+ *    Function Name : InitiateProtocol()
+ *    Description   : do some initial works.
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+static void
+InitiateProtocol ()
+{
+  ximlist = (XIMContextList) NULL;
+
+  imattr_list_size = CreateAttrList (im_attr, imattr_list);
+  icattr_list_size = CreateAttrList (ic_attr, icattr_list);
+}
+
+/*
+ *    Function Name : CheckInputStyle()
+ *    Description   : check if the passed input style is supported.
+ *    Parameter     :
+ *      input_style : the input style to be checked.
+ *    Returned Value:
+ *      True        : supported.
+ *      False       : not supported.
+ */
+static Bool
+CheckInputStyle (input_style)
+     INT32 input_style;
+{
+  int i;
+
+  for (i = 0; i < MAX_SUPPORT_STYLE; i++)
+    {
+      if (xim->supported_style[i] == input_style)
+        {
+          return True;
+        }
+    }
+  return False;
+}
+
+/*
+ *    Function Name : ConvErrorCode()
+ *    Description   : convert error code used in Xsi R5 IM to R6 IM.
+ *    Parameter     :
+ *      x11r5_code  : error code of Xsi R5 IM.
+ *    Returned Value:
+ *      > 0         : errro code of R6 IM 
+ */
+static int
+ConvErrorCode (x11r5_code)
+     short x11r5_code;
+{
+  switch (x11r5_code)
+    {
+    case AllocError:
+      return XIM_BadAlloc;
+    case BadStyle:
+      return XIM_BadStyle;
+    case BadClientWindow:
+      return XIM_BadClientWindow;
+    case BadFocusWindow:
+      return XIM_BadFocusWindow;
+    case BadLanguage:
+      return XIM_LocaleNotSupported;
+    case BadSpotLocation:
+      return XIM_BadSpotLocation;
+    case BadFontSet:
+      return XIM_BadName;       /* or XIM_BadStyle */
+    default:
+      return XIM_BadSomething;
+    }
+}
+
+/*
+ *    Function Name : ConvAreaAttr()
+ *    Description   : convert byte data to IC attribute of Area.
+ *    Parameter     :
+ *      value       : the byte data.
+ *      size        : byte length of the data.
+ *      ic_attr_req : contain Area attribute to be filled.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+ConvAreaAttr (value, size, ic_attr_req)
+     CARD8 *value;
+     int size;
+     ximICAttributesReq *ic_attr_req;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+
+  if (size != (sizeof (CARD16) << 2))
+    return XIM_BadAlloc;
+
+  ic_attr_req->area_x = (INT16) GET_CARD16 (buf_16[0]);
+  ic_attr_req->area_y = (INT16) GET_CARD16 (buf_16[1]);
+  ic_attr_req->area_width = GET_CARD16 (buf_16[2]);
+  ic_attr_req->area_height = GET_CARD16 (buf_16[3]);
+  return 0;
+}
+
+/*
+ *    Function Name : ConvAreaNeededAttr()
+ *    Description   : convert byte data to IC attribute of AreaNeeded.
+ *    Parameter     :
+ *      value       : the byte data.
+ *      size        : byte length of the data.
+ *      ic_attr_req : contain AreaNeeded attribute to be filled.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+ConvAreaNeededAttr (value, size, ic_attr_req)
+     CARD8 *value;
+     int size;
+     ximICAttributesReq *ic_attr_req;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+
+  if (size != (sizeof (CARD16) << 2))
+    return XIM_BadAlloc;
+
+  ic_attr_req->areaneeded_width = GET_CARD16 (buf_16[2]);
+  ic_attr_req->areaneeded_height = GET_CARD16 (buf_16[3]);
+  return 0;
+}
+
+/*
+ *    Function Name : ConvSpotAttr()
+ *    Description   : convert byte data to IC attribute of Spot.
+ *    Parameter     :
+ *      value       : the byte data.
+ *      size        : byte length of the data.
+ *      ic_attr_req : contain Spot attribute to be filled.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+ConvSpotAttr (value, size, ic_attr_req)
+     CARD8 *value;
+     int size;
+     ximICAttributesReq *ic_attr_req;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+
+  if (size != (sizeof (CARD16) + sizeof (CARD16)))
+    return XIM_BadAlloc;
+
+  ic_attr_req->spot_x = (INT16) GET_CARD16 (buf_16[0]);
+  ic_attr_req->spot_y = (INT16) GET_CARD16 (buf_16[1]);
+  return 0;
+}
+
+/*
+ *    Function Name : ConvFontSetAttr()
+ *    Description   : convert byte data to IC attribute of FontSet name.
+ *    Parameter     :
+ *      value       : the byte data.
+ *      size        : byte length of the data.
+ *      ic_attr_req : contain FontSet attribute to be filled.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+ConvFontSetAttr (value, size, base_font_name)
+     CARD8 *value;
+     int size;
+     char **base_font_name;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+  char *fname;
+  int len;
+
+  len = (int) GET_CARD16 (buf_16[0]);
+  if (len > size)
+    return XIM_BadAlloc;
+  if (!(fname = Malloc (len + 1)))
+    return XIM_BadAlloc;
+  (void) strncpy (fname, (char *) &buf_16[1], len);
+  fname[len] = '\0';
+  *base_font_name = fname;
+  return 0;
+}
+
+/*
+ *    Function Name : DecodeICNestedAttributes()
+ *    Description   : decode IC nested attributes
+ *    Parameter     :
+ *      list        : list of IC attribute, packed data. 
+ *      size        : byte length of list.
+ *      ic_attr_req : IC attribute structure to be filled.
+ *      font        : base font name to be returned.  The caller should
+ *                    free it after use.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+DecodeICNestedAttributes (list, size, mask, ic_attr_req, font)
+     CARD8 *list;
+     int size;
+     CARD32 *mask;
+     ximICAttributesReq *ic_attr_req;
+     char **font;
+{
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  CARD32 mask_base, mask_ret;
+  int ret, have_more;
+  int len, tmpl, attr_id;
+
+  ret = 0;
+  mask_base = *mask;
+  mask_ret = 0;
+  have_more = 1;
+  while (size > 0 && have_more)
+    {
+      buf_16 = (CARD16 *) list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);   /* 2 attribute id */
+      len = (int) GET_CARD16 (buf_16[1]);       /* n length of value */
+      tmpl = sizeof (CARD16) + sizeof (CARD16);
+      list += tmpl;
+      size -= tmpl;
+      buf_16 = (CARD16 *) list;
+      buf_32 = (CARD32 *) list;
+      switch (attr_id)
+        {
+        case ICArea:
+          mask_ret |= (1 << (ICArea + mask_base));
+          ret = ConvAreaAttr (list, len, ic_attr_req);
+          break;
+        case ICAreaNeeded:
+          mask_ret |= (1 << (ICAreaNeeded + mask_base));
+          ret = ConvAreaNeededAttr (list, len, ic_attr_req);
+          break;
+        case ICSpotLocation:
+          mask_ret |= (1 << (ICSpotLocation + mask_base));
+          ret = ConvSpotAttr (list, len, ic_attr_req);
+          break;
+        case ICColormap:
+          mask_ret |= (1 << (ICColormap + mask_base));
+          ic_attr_req->colormap = (Colormap) GET_CARD32 (buf_32[0]);
+          break;
+        case ICStdColormap:
+          mask_ret |= (1 << (ICStdColormap + mask_base));
+          ic_attr_req->std_colormap = (Atom) GET_CARD32 (buf_32[0]);
+          break;
+        case ICForeground:
+          mask_ret |= (1 << (ICForeground + mask_base));
+          ic_attr_req->foreground = GET_CARD32 (buf_32[0]);
+          break;
+        case ICBackground:
+          mask_ret |= (1 << (ICBackground + mask_base));
+          ic_attr_req->background = GET_CARD32 (buf_32[0]);
+          break;
+        case ICBackgroundPixmap:
+          mask_ret |= (1 << (ICBackgroundPixmap + mask_base));
+          ic_attr_req->pixmap = (Pixmap) GET_CARD32 (buf_32[0]);
+          break;
+        case ICFontSet:
+          mask_ret |= (1 << (ICFontSet + mask_base));
+          ret = ConvFontSetAttr (list, len, font);
+          break;
+        case ICLineSpace:
+          mask_ret |= (1 << (ICLineSpace + mask_base));
+          ic_attr_req->line_space = (INT16) GET_CARD32 (buf_32[0]);
+          break;
+        case ICCursor:
+          mask_ret |= (1 << (ICCursor + mask_base));
+          ic_attr_req->cursor = (Cursor) GET_CARD32 (buf_32[0]);
+          break;
+        case ICSeparatorOfNestedList:
+          have_more = 0;
+          break;
+        default:
+          have_more = 0;
+          continue;
+        }
+      if (ret)
+        return ret;
+      len = len +               /* n value */
+        PAD (len);              /* p Pad(n) */
+      list += len;
+      size -= len;
+    }
+  *mask = mask_ret;
+  return 0;
+}
+
+/*
+ *    Function Name : DecodeICAttributes()
+ *    Description   : parse all IC attributes
+ *    Parameter     :
+ *      list        : list of IC attributes, packed data.
+ *      size        : byte length of list.
+ *      ic_attr_req : IC attribute structure to be filled.
+ *      pre_req     : preedit attributes to be filled.
+ *      st_req      : status attributes to be filled.
+ *      pre_font    : preedit base font name to be returned.  The caller should
+ *                    free it after use.
+ *      st_font     : status base font name to be returned.  The caller should
+ *                    free it after use.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+DecodeICAttributes (list, size, ic_req, pre_req, st_req, pre_font, st_font)
+     CARD8 *list;
+     int size;
+     ximICValuesReq *ic_req;
+     ximICAttributesReq *pre_req;
+     ximICAttributesReq *st_req;
+     char **pre_font;
+     char **st_font;
+{
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  CARD32 mask;
+  int ret, len, attr_id;
+  int tmpl;
+
+  ret = 0;
+  ic_req->mask = (CARD32) 0;
+  while (size > 0)
+    {
+      buf_16 = (CARD16 *) list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);
+      len = (int) GET_CARD16 (buf_16[1]);
+      tmpl = sizeof (CARD16) +  /* 2 attribute id */
+        sizeof (CARD16);        /* 2 value length */
+      list += tmpl;
+      size -= tmpl;
+      buf_16 = (CARD16 *) list;
+      buf_32 = (CARD32 *) list;
+      switch (attr_id)
+        {
+        case ICInputStyle:
+          ic_req->mask |= (1 << ICInputStyle);
+          ic_req->input_style = (INT32) GET_CARD32 (buf_32[0]);
+          break;
+        case ICClientWindow:
+          ic_req->mask |= (1 << ICClientWindow);
+          ic_req->c_window = (Window) GET_CARD32 (buf_32[0]);
+          break;
+        case ICFocusWindow:
+          ic_req->mask |= (1 << ICFocusWindow);
+          ic_req->focus_window = (Window) GET_CARD32 (buf_32[0]);
+          break;
+        case ICFilterEvents:
+          ic_req->mask |= (1 << ICFilterEvents);
+          ic_req->filter_events = GET_CARD32 (buf_32[0]);
+          break;
+        case ICPreeditAttributes:
+          mask = 0;
+          ret = DecodeICNestedAttributes (list, len, &mask, pre_req, pre_font);
+          ic_req->mask |= mask;
+          break;
+        case ICStatusAttributes:
+          mask = StatusOffset;
+          ret = DecodeICNestedAttributes (list, len, &mask, st_req, st_font);
+          ic_req->mask |= mask;
+          break;
+        default:
+          ret = XIM_BadProtocol;
+          break;
+        }
+      if (ret)
+        return ret;
+      len = len +               /* n value */
+        PAD (len);              /* p Pad(n) */
+      list += len;
+      size -= len;
+    }
+  return 0;
+}
+
+/*
+ *    Function Name : SetClientICValues()
+ *    Description   : set IC values to a client structure.
+ *    Parameter     :
+ *      list        : list of IC attributes, packed data.
+ *      size        : byte length of list.
+ *      xc          : pointer to client structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SetClientICValues (list, size, xc)
+     CARD8 *list;
+     int size;
+     XIMClientRec *xc;
+{
+  ximICValuesReq ic_req;
+  ximICAttributesReq pre_req, st_req;
+  XIMNestLangRec *p = (XIMNestLangRec *) NULL;
+  char *pre_font = (char *) NULL;
+  char *st_font = (char *) NULL;
+  int cur_is_world = 0;
+  int ret;
+  short detail;
+  extern int change_client ();
+
+  /* parse IC attributes */
+  ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
+  if (ret)
+    return ret;
+
+  /* refer to util: ChangeIC() */
+
+  ret = change_client (xc, &ic_req, &pre_req, &st_req, p, cur_is_world, pre_font, st_font, &detail);
+  if (pre_font)
+    XFree (pre_font);
+  if (st_font)
+    XFree (st_font);
+  if (p)
+    free_langlist (p);
+  if (ret == -1)
+    return ConvErrorCode (detail);
+  return 0;
+}
+
+/*
+ *    Function Name : EncodeRectangleAttr()
+ *    Description   : encode XRectangle to byte data.
+ *    Parameter     :
+ *      rect        : pointer to the rectangle structure.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeRectangleAttr (rect, value, size_return)
+     XRectangle *rect;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+
+  buf_16[0] = GET_CARD16 (rect->x);
+  buf_16[1] = GET_CARD16 (rect->y);
+  buf_16[2] = GET_CARD16 (rect->width);
+  buf_16[3] = GET_CARD16 (rect->height);
+  *size_return = sizeof (CARD16) +      /* 2 X */
+    sizeof (CARD16) +           /* 2 Y */
+    sizeof (CARD16) +           /* 2 width */
+    sizeof (CARD16);            /* 2 height */
+  return 0;
+}
+
+/*
+ *    Function Name : EncodePointAttr()
+ *    Description   : encode XPoint to byte data.
+ *    Parameter     :
+ *      rect        : pointer to the XPoint structure.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodePointAttr (xc, value, size_return)
+     XIMClientRec *xc;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+  short spot_x, spot_y;
+
+  spot_x = xc->point.x;
+  spot_y = xc->point.y + FontAscent (xc->cur_xl);
+  buf_16[0] = GET_CARD16 (spot_x);
+  buf_16[1] = GET_CARD16 (spot_y);
+  *size_return = sizeof (CARD16) +      /* 2 X */
+    sizeof (CARD16);            /* 2 Y */
+  return 0;
+}
+
+/*
+ *    Function Name : EncodeFontSetAttr()
+ *    Description   : encode name of base font set to byte data.
+ *    Parameter     :
+ *      rect        : pointer to the name.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeFontSetAttr (base_font_name, value, size_return)
+     char *base_font_name;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+  int len;
+
+  len = strlen ((char *) base_font_name);
+  buf_16[0] = GET_CARD16 (len);
+  (void) strncpy ((char *) &buf_16[1], (char *) base_font_name, len);
+  *size_return = sizeof (CARD16) + len + PAD (sizeof (CARD16) + len);
+  return 0;
+}
+
+/*
+ *    Function Name : EncodeICNestedAttributes()
+ *    Description   : encode IC nested attribute structure to byte data.
+ *    Parameter     :
+ *      attr_id_list: list of IC attribute id.
+ *      size        : byte lenth of the list.
+ *      xc          : pointer to client structure.
+ *      ic_attr     : pointer to IC nested attribute structure.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *      num_return  : returned number of IC attributes.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeICNestedAttributes (attr_id_list, size, xc, ic_attr, value, size_return, num_return)
+     CARD8 *attr_id_list;
+     int size;
+     XIMClientRec *xc;
+     XIMAttributes *ic_attr;
+     CARD8 *value;
+     int *size_return;
+     int *num_return;
+{
+  CARD8 *data;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int ret, len, total, num, attr_id;
+  int have_more;
+
+  ret = 0;
+  total = num = 0;
+  have_more = 1;
+  while (size > 0 && have_more)
+    {
+      buf_16 = (CARD16 *) attr_id_list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);
+      data = value + sizeof (CARD16) + sizeof (CARD16);
+      buf_16 = (CARD16 *) data;
+      buf_32 = (CARD32 *) data;
+      switch (attr_id)
+        {
+        case ICArea:
+          ret = EncodeRectangleAttr (&(ic_attr->area), data, &len);
+          break;
+        case ICAreaNeeded:
+          ret = EncodeRectangleAttr (&(ic_attr->area_needed), data, &len);
+          break;
+        case ICSpotLocation:
+          ret = EncodePointAttr (xc, data, &len);
+          break;
+        case ICColormap:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->colormap);
+          break;
+        case ICStdColormap:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->std_colormap);
+          break;
+        case ICForeground:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->fg);
+          break;
+        case ICBackground:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->bg);
+          break;
+        case ICBackgroundPixmap:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->bg_pixmap);
+          break;
+        case ICFontSet:
+          ret = EncodeFontSetAttr (ic_attr->fontset, data, &len);
+          break;
+        case ICLineSpace:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->line_space);
+          break;
+        case ICCursor:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (ic_attr->cursor);
+          break;
+        case ICSeparatorOfNestedList:
+          len = 0;
+          have_more = 0;
+          break;
+        default:
+          have_more = 0;
+          continue;
+        }
+      if (ret)
+        return ret;
+      buf_16 = (CARD16 *) value;
+      buf_16[0] = GET_CARD16 (attr_id);
+      buf_16[1] = GET_CARD16 (len);
+      len = sizeof (CARD16) +   /* 2 attribute-id */
+        sizeof (CARD16) +       /* 2 byte length of value */
+        len +                   /* n value */
+        PAD (len);              /* p Pad(n) */
+      value += len;
+      total += len;
+      attr_id_list += sizeof (CARD16);
+      size -= sizeof (CARD16);
+      num++;
+    }
+  *size_return = total;
+  *num_return = num;
+  return 0;
+}
+
+/*
+ *    Function Name : EncodeICAttributes()
+ *    Description   : encode IC attribute structure to byte data.
+ *    Parameter     :
+ *      attr_id_list: list of IC attribute id.
+ *      size        : byte lenth of the list.
+ *      xc          : pointer to client structure.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeICAttributes (attr_id_list, size, xc, value, size_return)
+     CARD8 *attr_id_list;
+     int size;
+     XIMClientRec *xc;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD8 *data;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int ret, len, total, attr_id, num;
+  int nested_size;
+
+  ret = 0;
+  total = 0;
+  while (size > 0)
+    {
+      buf_16 = (CARD16 *) attr_id_list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);
+      data = value + sizeof (CARD16) + sizeof (CARD16);
+      buf_16 = (CARD16 *) data;
+      buf_32 = (CARD32 *) data;
+      switch (attr_id)
+        {
+        case ICInputStyle:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (xc->input_style);
+          break;
+        case ICClientWindow:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (xc->w);
+          break;
+        case ICFocusWindow:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (xc->focus_window);
+          break;
+        case ICFilterEvents:
+          len = sizeof (CARD32);
+          buf_32[0] = GET_CARD32 (xc->filter_events);
+          break;
+        case ICPreeditAttributes:
+          ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->pe), data, &len, &num);
+          if (!ret)
+            {
+              nested_size = sizeof (CARD16) * num;
+              attr_id_list += nested_size;
+              size -= nested_size;
+            }
+          break;
+        case ICStatusAttributes:
+          ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->st), data, &len, &num);
+          if (!ret)
+            {
+              nested_size = sizeof (CARD16) * num;
+              attr_id_list += nested_size;
+              size -= nested_size;
+            }
+          break;
+        default:
+          ret = XIM_BadProtocol;
+        }
+      if (ret)
+        return ret;
+      buf_16 = (CARD16 *) value;
+      buf_16[0] = GET_CARD16 (attr_id);
+      buf_16[1] = GET_CARD16 (len);
+      len = sizeof (CARD16) +   /* 2 attribute-id */
+        sizeof (CARD16) +       /* 2 byte length of value */
+        len +                   /* n value */
+        PAD (len);              /* p Pad(n) */
+      value += len;
+      total += len;
+      attr_id_list += sizeof (CARD16);
+      size -= sizeof (CARD16);
+    }
+  *size_return = total;
+  return 0;
+}
+
+/*
+ *    Function Name : DecodeIMAttributes()
+ *    Description   : decode IM attributes.
+ *    Parameter     :
+ *      list        : list of IM attribute, packed data.
+ *      size        : byte length of list.
+ *      extension   : not used.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+ /*ARGSUSED*/ static int
+DecodeIMAttributes (list, size, extension)
+     CARD8 *list;
+     int size;
+     XPointer extension;        /* for extenstion in future */
+{
+  CARD16 *buf_16;
+  int ret, len, attr_id;
+
+  ret = 0;
+  while (size > 0)
+    {
+      buf_16 = (CARD16 *) list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);
+      len = (int) GET_CARD16 (buf_16[1]);
+      switch (attr_id)
+        {
+        case ICInputStyle:
+          /* we don't allow to set InputStyle so far. */
+          ret = XIM_BadStyle;
+          break;
+        default:
+          /* no more supported so far */
+          ret = XIM_BadSomething;
+        }
+      if (ret)
+        return ret;
+      len += sizeof (CARD16) +  /* 2 attribute-id */
+        sizeof (CARD16) +       /* 2 n byte lenght of attr */
+        len +                   /* n value of attr */
+        PAD (len);              /* p Pad(n) */
+      list += len;
+      size -= len;
+    }
+  return 0;
+}
+
+/*
+ *    Function Name : SetClientIMValues()
+ *    Description   : decode IM values to client context.
+ *    Parameter     :
+ *      value       : IM values, packed data.
+ *      size        : byte length of list.
+ *      im          : client IM context.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SetClientIMValues (value, size, im)
+     CARD8 *value;
+     int size;
+     XIMContextRec *im;
+{
+  /* no any attribute can be set so far */
+  return DecodeIMAttributes (value, size, (XPointer) NULL);
+}
+
+/*
+ *    Function Name : EncodeInputStyleList()
+ *    Description   : encode Input Style list to byte data.
+ *    Parameter     :
+ *      im          : pointer to client IM context.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeInputStyleList (im, value, size_return)
+     XIMContextRec *im;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD16 *buf_16 = (CARD16 *) value;
+  CARD32 *buf_32 = (CARD32 *) & buf_16[2];
+  int num, i;
+
+  num = MAX_SUPPORT_STYLE - 1;
+  buf_16[0] = GET_CARD16 (num);
+  for (i = 0; i <= num; i++)
+    {
+      buf_32[i] = GET_CARD32 (xim->supported_style[i]);
+    }
+  *size_return = sizeof (CARD16) +      /* 2 number of list */
+    sizeof (CARD16) +           /* 2 unused */
+    sizeof (CARD32) * MAX_SUPPORT_STYLE;
+  return 0;
+}
+
+/*
+ *    Function Name : EncodeIMAttributes()
+ *    Description   : encode IM attribute structure to byte data.
+ *    Parameter     :
+ *      attr_id_list: list of attribute id.
+ *      size        : byte length of the list.
+ *      im          : pointer to client IM context.
+ *      value       : encoded byte data.
+ *      size_return : returned byte length of the data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeIMAttributes (attr_id_list, size, im, value, size_return)
+     CARD8 *attr_id_list;
+     int size;
+     XIMContextRec *im;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD8 *data;
+  CARD16 *buf_16;
+  int ret, len, total, attr_id;
+
+  ret = 0;
+  total = 0;
+  while (size > 0)
+    {
+      buf_16 = (CARD16 *) attr_id_list;
+      attr_id = (int) GET_CARD16 (buf_16[0]);
+      data = value + sizeof (CARD16) + sizeof (CARD16);
+      switch (attr_id)
+        {
+        case ICInputStyle:
+          ret = EncodeInputStyleList (im, data, &len);
+          break;
+        default:
+          ret = XIM_BadSomething;
+        }
+      if (ret)
+        return ret;
+      buf_16 = (CARD16 *) value;
+      buf_16[0] = GET_CARD16 (attr_id);
+      buf_16[1] = GET_CARD16 (len);
+      len = sizeof (CARD16) +   /* 2 attribute-id */
+        sizeof (CARD16) +       /* 2 byte length of value */
+        len +                   /* n value */
+        PAD (len);              /* p Pad(n) */
+      value += len;
+      total += len;
+      attr_id_list += sizeof (CARD16);
+      size -= sizeof (CARD16);
+    }
+  *size_return = total;
+  return 0;
+}
+
+/*
+ *    Function Name : CreateClientIC()
+ *    Description   : create an IC context and assign a new IC id.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      list        : list of IC attributes, packed data.
+ *      size        : byte length of list.
+ *      ic_id_return: new IC id of the create IC context.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+CreateClientIC (im_id, list, size, ic_id_return)
+     XIMID im_id;
+     CARD8 *list;
+     int size;
+     XICID *ic_id_return;
+{
+  XIMClientRec *xc;
+  ximICValuesReq ic_req;
+  ximICAttributesReq pre_req, st_req;
+  char *pre_font = (char *) NULL;
+  char *st_font = (char *) NULL;
+  XIMNestLangList lc_list = (XIMNestLangList) NULL;
+  XIMNestLangList cur_lc = (XIMNestLangList) NULL;
+  XIMNestLangList p;
+  int have_world = 0, cur_is_world = 0;
+  char *use_langs, *cur_l, *c_data;
+  int xic, ret, i;
+  short detail;
+  extern XIMClientRec *create_client ();
+
+  /*
+   * parse attributes
+   */
+  ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
+  if (ret)
+    return ret;
+  ic_req.max_keycode = 0;       /* set 0 as default */
+
+  use_langs = cur_use_lang;     /* use locale from XIM_OPEN */
+  cur_l = (char *) NULL;        /* current lang not specified yet. */
+  c_data = (char *) NULL;       /* default user name. */
+
+  /* refer to util.c: CreateIC() */
+
+  /*
+   * check resources.
+   */
+  if (CheckInputStyle (ic_req.input_style) == False)
+    return XIM_BadStyle;
+  if ((ic_req.input_style & (XIMPreeditArea | XIMPreeditPosition)) && (!(ic_req.mask & (1 << ICFontSet)) || !pre_font || !*pre_font))
+    return XIM_BadName;
+  if ((ic_req.input_style & XIMStatusArea) && (!(ic_req.mask & (1 << (ICFontSet + StatusOffset))) || !st_font || !*st_font))
+    return XIM_BadName;
+  if ((ic_req.input_style & XIMPreeditPosition) && (!(ic_req.mask & (1 << ICSpotLocation))))
+    return XIM_BadSpotLocation;
+  if (!(ic_req.input_style & XIMPreeditNothing))
+    {
+      if ((have_world = get_langlist (use_langs, &lc_list)) < 0)
+        {
+          return XIM_BadAlloc;
+        }
+      if (!lc_list)
+        {
+          return XIM_LocaleNotSupported;
+        }
+      if (cur_l && *cur_l)
+        {
+          for (p = lc_list; p != NULL; p = p->next)
+            {
+              if (!strcmp (p->lc_name, cur_l) || (p->alias_name && !strcmp (p->alias_name, cur_l)))
+                break;
+            }
+          if (p == NULL)
+            {
+              if ((i = get_langlist (cur_l, &cur_lc)) < 0)
+                {
+                  return XIM_BadAlloc;
+                }
+              else if (i > 0)
+                {
+                  cur_is_world++;
+                  free_langlist (cur_lc);
+                  cur_lc = lc_list;
+                }
+              else
+                {
+                  if (cur_lc)
+                    {
+                      cur_lc->next = lc_list;
+                    }
+                  else
+                    {
+                      cur_lc = lc_list;
+                    }
+                }
+            }
+          else
+            {
+              cur_lc = p;
+            }
+        }
+      else
+        {
+          if (have_world == 2)
+            cur_is_world++;
+          cur_lc = lc_list;
+        }
+    }
+  xc = create_client (&ic_req, &pre_req, &st_req, lc_list, cur_lc, have_world, cur_is_world, pre_font, st_font, c_data, &detail);
+  if (pre_font)
+    XFree (pre_font);
+  if (st_font)
+    XFree (st_font);
+  if (lc_list)
+    free_langlist (lc_list);
+  if (!xc)
+    {
+      return ConvErrorCode (detail);
+    }
+  xic = xim->client_count++;
+  xc->number = xic;
+  xc->im_id = (int) im_id;
+  if (IsPreeditNothing (xc))
+    {
+      check_root_mapping (xc->root_pointer);
+    }
+
+  *ic_id_return = (XICID) xic;
+  return 0;
+}
+
+/*
+ *    Function Name : CreateIM()
+ *    Description   : create a new IM context and register in the list.
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      > 0         : IM id of the new IM context created.
+ *      = 0         : error
+ */
+static XIMID
+CreateIM ()
+{
+  static XIMID base_im_id = BASE_IM_ID;
+  XIMContextRec *im;
+
+  im = (XIMContextRec *) Malloc (sizeof (XIMContextRec));
+  if (!im)
+    {
+      malloc_error ("no memory to open an IM");
+      return 0;
+    }
+  im->im_id = ALLOC_ID (base_im_id);
+
+  /* add to IM list */
+  im->next = ximlist;
+  ximlist = im;
+  return im->im_id;
+}
+
+/*
+ *    Function Name : GetCompoundTextIndex()
+ *    Description   : search the index of string named COMPOUND_TEXT in
+ *                    LISTofSTR. 
+ *    Parameter     :
+ *      list        : list of string names LISTofSTR.
+ *      size        : byte length of the list.
+ *    Returned Value:
+ *      int         : returned index in this list. If not found, it is
+ *                    the default XIM_Default_Encoding_IDX.
+ */
+static int
+GetCompoundTextIndex (list, size)
+     register CARD8 *list;
+     register int size;
+{
+  register int index, len;
+
+  /* get index of COMPOUNT_TEXT which is only supported by us. */
+  index = 0;
+  while (size > 0)
+    {
+      len = (int) list[0];
+      if (!strncmp (&list[1], "COMPOUND_TEXT", len))
+        break;
+      index++;
+      list += (sizeof (CARD8) + len);
+      size -= (sizeof (CARD8) + len);
+    };
+  if (size == 0)
+    index = XIM_Default_Encoding_IDX;   /* use default */
+  return index;
+}
+
+/*
+ *    Function Name : FindExtensionByName()
+ *    Description   : search an extension item with its name in extension
+ *                    list supported by this server.
+ *    Parameter     :
+ *      name        : ext string name.
+ *      len         : length of ext name.
+ *    Returned Value:
+ *      >= 0        : found item index to this list.
+ *      = -1        : not found.
+ */
+static int
+FindExtensionByName (name, len)
+     char *name;
+     int len;
+{
+  int ind;
+
+  for (ind = 0; ind < XIMNumber (extension_list); ind++)
+    {
+      if (!strncmp (extension_list[ind].name, name, len))
+        return ind;
+    }
+  return -1;
+}
+
+/*
+ *    Function Name : EncodeExtension()
+ *    Description   : encode an extension item to byte data.
+ *    Parameter     :
+ *      ind         : the item index to extension list.
+ *      value       : byte data to store the packed ext item.
+ *      size_return : returned byte size of the packed ext item
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+EncodeExtension (ind, value, size_return)
+     int ind;
+     CARD8 *value;
+     int *size_return;
+{
+  CARD16 *buf_16 = (CARD16 *) & value[2];
+  int len;
+
+  len = strlen (extension_list[ind].name);
+  value[0] = extension_list[ind].major_code;
+  value[1] = extension_list[ind].minor_code;
+  buf_16[0] = GET_CARD16 (len);
+  (void) strncpy ((char *) &buf_16[1], extension_list[ind].name, len);
+  *size_return = sizeof (CARD8) +       /* 1 major_code */
+    sizeof (CARD8) +            /* 1 minor_code */
+    sizeof (CARD16) +           /* 2 n length of name */
+    len +                       /* n name */
+    PAD (len);                  /* p Pad(n) */
+  return 0;
+}
+
+/*
+ *    Function Name : GetExtensionList()
+ *    Description   : get extensions supported by the server. 
+ *    Parameter     :
+ *      list        : list of extension names asked by client.
+ *      size        : byte length of the list, if it is zero, client asks
+ *                    all extensions supported by the server.
+ *      value       : the returned exension names supported by server. It is
+ *                    packed in byte.
+ *      size_return : returned byte size of the packed ext names.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+GetExtensionList (list, size, value, size_return)
+     CARD8 *list;
+     int size;
+     CARD8 *value;
+     int *size_return;
+{
+  int len, ext_len, ind, total;
+
+  total = 0;
+  if (size == 0)
+    {
+      for (ind = 0; ind < XIMNumber (extension_list); ind++)
+        {
+          (void) EncodeExtension (ind, value, &ext_len);
+          value += ext_len;
+          total += ext_len;
+        }
+    }
+  else
+    {
+      while (size > 0)
+        {
+          len = (int) list[0];
+          if ((ind = FindExtensionByName ((char *) &list[1], len)) >= 0)
+            {
+              (void) EncodeExtension (ind, value, &ext_len);
+              value += ext_len;
+              total += ext_len;
+            }
+          list += (sizeof (CARD8) + len);
+          size -= (sizeof (CARD8) + len);
+        }
+    }
+  *size_return = total;
+  return 0;
+}
+
+/*
+ *    Function Name : RecvRequest()
+ *    Description   : receive a request of XIM protocol from IM library.
+ *    Parameter     :
+ *      req         : pointer to a request structure, returned.
+ *    Returned Value:
+ *      >=0         : byte length of request data except request head.
+ *      < 0         : error in reading data.
+ */
+static int
+RecvRequest (req)
+     XimRequestPacket *req;
+{
+  CARD8 *buf, *read_ptr;
+  CARD8 byteOrder;
+  int read_size;
+  extern char my_byteOrder;
+
+  if (_ReadFromClient ((char *) req, XIM_HEADER_SIZE) == -1)
+    return -1;
+  if (req->length == 0)
+    return 0;
+  read_size = req->length * 4;
+  read_ptr = buf = MALLOC_REQUEST (read_size);
+  bzero ((char *) buf, read_size);
+  if (req->major_opcode == XIM_CONNECT)
+    {
+      _ReadFromClient ((char *) &byteOrder, 1);
+      if (my_byteOrder != (char) byteOrder)
+        cur_cblk->byteOrder = True;
+      else
+        cur_cblk->byteOrder = False;
+      buf[0] = byteOrder;
+      read_ptr = &buf[1];
+      read_size--;
+    }
+  if (_ReadFromClient (read_ptr, read_size) == -1)
+    {
+      FREE (buf);
+      return -1;
+    }
+  req->data = buf;
+  return req->length * 4;
+}
+
+/*
+ *    Function Name : SendIdOnly()
+ *    Description   : send a request that is the format of:
+ *                        CARD16 input-method-id
+ *                        CARD16 input-context-id
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      major_code  : major opcode of this request.
+ *      minor_code  : minor opcode of this request.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendIdOnly (im_id, ic_id, major_code, minor_code)
+     XIMID im_id;
+     XICID ic_id;
+     CARD8 major_code;
+     CARD8 minor_code;
+{
+  CARD16 *buf_16;
+  CARD8 *reply;
+  int len;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16);            /* 2 input-context-ID */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, major_code, minor_code, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendSyncReply()
+ *    Description   : If server has not syncronized, do sync. Then
+ *                    send a XIM_SYNC_REPLY to IM library.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendSyncReply (im_id, ic_id)
+     XIMID im_id;
+     XICID ic_id;
+{
+  if (!AllSyncDone (im_id, ic_id))
+    {
+      SyncAll (im_id, ic_id);
+    }
+  return SendIdOnly (im_id, ic_id, XIM_SYNC_REPLY, 0);
+}
+
+/*
+ *    Function Name : RecvSync()
+ *    Description   : process of client request XIM_SYNC.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvSync (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!GetICWithId (ic_id))
+    return XIM_BadProtocol;
+
+  return SendSyncReply (im_id, ic_id);
+}
+
+/*
+ *    Function Name : RecvSyncReply()
+ *    Description   : process of client request XIM_SYNC_REPLY.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvSyncReply (req)
+     XimRequestPacket *req;
+{
+  /* no action. */
+  return 0;
+}
+
+/*
+ *    Function Name : RecvError()
+ *    Description   : process of client request XIM_ERROR.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvError (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;                  /* not used yet */
+  XICID ic_id;                  /* not used yet */
+  int eflag, ecode, esnum;
+
+  im_id = (XIMID) GET_CARD16 (buf_16[0]);       /* 2 input-method-ID */
+  ic_id = (XICID) GET_CARD16 (buf_16[1]);       /* 2 input-context-ID */
+  eflag = (int) GET_CARD16 (buf_16[2]); /* 2 flag */
+  ecode = (int) GET_CARD16 (buf_16[3]); /* 2 error code */
+  esnum = (int) GET_CARD16 (buf_16[4]); /* 2 n length */
+  if (esnum > 0)
+    {
+      char *emsg;
+      if (!(emsg = Malloc (esnum + 1)))
+        {
+          return XIM_BadAlloc;
+        }
+      (void) strncpy (emsg, (char *) &buf_16[6], esnum);
+      emsg[esnum] = '\0';
+      print_out3 ("XIM Protocol Error: %d %s\n", ecode, emsg);
+      XFree (emsg);
+    }
+  else
+    {
+      print_out2 ("XIM Protocol Error: %d\n", ecode);
+    }
+  return 0;
+}
+
+/*
+ *    Function Name : SendError()
+ *    Description   : send error message to IM library with the request
+ *                    XIM_ERROR.
+ *    Parameter     :
+ *      err_code    : error code.
+ *    Returned Value:
+ *      <none>
+ */
+static void
+SendError (err_code)
+     CARD16 err_code;
+{
+  CARD16 *buf_16;
+  CARD8 *reply;
+  int len;
+
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (BITMASK16) +        /* 2 flag */
+    sizeof (CARD16) +           /* 2 error code */
+    sizeof (INT16) +            /* 2 byte length of error detail */
+    sizeof (CARD16);            /* 2 type of error detail */
+/* empty *//* n error detail */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_ERROR, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (cur_im_id);
+  buf_16[1] = GET_CARD16 (cur_ic_id);
+  buf_16[2] = GET_CARD16 (cur_status);
+  buf_16[3] = GET_CARD16 (err_code);
+  buf_16[4] = 0;                /* no error detail */
+  buf_16[5] = 0;                /* no type */
+  (void) _WriteToClientFlush (reply, len);
+  FREE (reply);
+}
+
+/*
+ *    Function Name : SendAuthRequired()
+ *    Description   : reply XIM_AUTH_REQUIRED as client ask auth.
+ *    Parameter     :
+ *      auth_index  : index of list of auth names.
+ *      auth_data   : auth data. 
+ *      length_data : byte length of data.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendAuthRequired (auth_index, auth_data, length_data)
+     CARD8 auth_index;
+     CARD8 *auth_data;
+     INT16 length_data;
+{
+  CARD8 *buf_8;
+  CARD16 *buf_16;
+  CARD8 *reply;
+  int len;
+
+  len = sizeof (CARD8) +        /* 1 auth-protocol_index */
+    sizeof (CARD8) * 3 +        /* 3 unused */
+    sizeof (CARD16) +           /* 2 length of auth data */
+    sizeof (CARD16) +           /* 2 unused */
+    length_data +               /* n data */
+    PAD (length_data);          /* p unused, p = Pad(n) */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_AUTH_REQUIRED, 0, len);
+  buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4);
+  buf_8[0] = (CARD8) auth_index;
+  buf_16[0] = GET_CARD16 (length_data);
+  if (auth_data && length_data > 0)
+    {
+      buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4 + sizeof (CARD16) * 2);
+      memcpy ((char *) buf_8, (char *) auth_data, length_data);
+    }
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendConnectReply()
+ *    Description   : reply connection from IM library.
+ *    Parameter     :
+ *      major_version
+ *                  : major version of XIM protocol
+ *      minor_version
+ *                  : minor version of XIM protocol
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendConnectReply (major_version, minor_version)
+     CARD16 major_version;
+     CARD16 minor_version;
+{
+  CARD16 *buf_16;
+  CARD8 *reply;
+  int len;
+
+  len = sizeof (CARD16) +       /* 2 server-major-protocol-version */
+    sizeof (CARD16);            /* 2 server-minor-protocol-version */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_CONNECT_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (major_version);
+  buf_16[1] = GET_CARD16 (minor_version);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvConnect()
+ *    Description   : do connection with IM client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvConnect (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) (req->data + 2);
+  CARD16 major_version, minor_version, auth_num;
+  int len;
+
+  len = req->length * 4;
+/* we have touched in RecvRequest *//* 1 byte order */
+/* not used *//* 1 unused */
+  major_version = GET_CARD16 (buf_16[0]);       /* 2 major protocol version */
+  minor_version = GET_CARD16 (buf_16[1]);       /* 2 minor protocol version */
+  auth_num = GET_CARD16 (buf_16[2]);    /* 2 number of auth. names */
+
+  if (major_version != PROTOCOLMAJORVERSION || minor_version != PROTOCOLMINORVERSION)
+    return XIM_BadProtocol;
+
+  len -= sizeof (CARD8) + sizeof (CARD8) + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16);
+
+  if (auth_num > 0)
+    {
+      if (GetAuth (&buf_16[3], auth_num, &len, NULL) == False)
+        {
+          return XIM_BadSomething;      /* error in get auth. */
+        }
+      return SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
+    }
+  else
+    {
+      return SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
+    }
+}
+
+/*
+ *    Function Name : RecvDisconnect()
+ *    Description   : disconnect with IM client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvDisconnect (req)
+     XimRequestPacket *req;
+{
+  CARD8 *reply;
+  int len;
+  extern int cur_sock;
+
+  close_socket (cur_sock);
+
+  /* reply */
+  len = 0;                      /* no data */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_DISCONNECT_REPLY, 0, len);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+#ifdef DYNAMIC_EVENT_FLOW_MODEL
+
+/*
+ *    Function Name : SendRegisterTriggerKeys()
+ *    Description   : ask client to register trigger keys which will
+ *                    turn on or off input method. 
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *    Returned Value:
+ *      <none>
+ */
+static void
+SendRegisterTriggerKeys (im_id)
+     XIMID im_id;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  CARD32 onkeys[3];
+  int onkeys_len;
+  int len;
+
+  onkeys[0] = GET_CARD32 (trigger_keys_list[0]);
+  onkeys[1] = GET_CARD32 (trigger_keys_list[1]);
+  onkeys[2] = GET_CARD32 (trigger_keys_list[2]);
+  onkeys_len = sizeof (CARD32) * 3;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 unused */
+    sizeof (CARD32) +           /* 4 n byte length */
+    onkeys_len +                /* n LISTofXIMTRIGGERKEY */
+    sizeof (CARD32) +           /* 4 m byte length */
+    onkeys_len;                 /* m LISTofXIMTRIGGERKEY */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_REGISTER_TRIGGERKEYS, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_32 = (CARD32 *) & buf_16[2];
+  buf_32[0] = GET_CARD32 (onkeys_len);
+  (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
+  buf_32 = (CARD32 *) (reply + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD32) + onkeys_len);
+  buf_32[0] = GET_CARD32 (onkeys_len);  /* off keys same as on-keys */
+  (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
+  (void) _WriteToClientFlush (reply, len);
+  FREE (reply);
+}
+
+/*
+ *    Function Name : ToggleHenkan()
+ *    Description   : turn on or off kanji henkan.
+ */
+static void
+ToggleHenkan (keys_index, mask)
+     int keys_index;
+     unsigned long mask;
+{
+  /* not yet */
+}
+
+/*
+ *    Function Name : RecvTriggerNotify()
+ *    Description   : Some trigger key has pressed by client, it means
+ *                    client asks some input method. do it.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvTriggerNotify (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD32 *buf_32;
+  CARD8 *reply;
+  XIMID im_id;
+  XICID ic_id;
+  int len;
+  int ret, n;
+  int keys_flag, keys_index;
+  unsigned long mask;
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  buf_32 = (CARD32 *) & buf_16[2];
+  keys_flag = (int) GET_CARD32 (buf_32[0]);
+  keys_index = (int) GET_CARD32 (buf_32[1]);
+  mask = (unsigned long) GET_CARD32 (buf_32[2]);
+
+  if (!keys_flag)
+    {
+      /* trigger on */
+      ToggleHenkan (keys_index, mask);
+    }
+  else
+    {
+      /* trigger off */
+      ToggleHenkan (keys_index, mask);
+    }
+
+  /* reply */
+  return SendIdOnly (im_id, ic_id, XIM_TRIGGER_NOTIFY_REPLY, 0);
+}
+
+#endif /* DYNAMIC_EVENT_FLOW_MODEL */
+
+/*
+ *    Function Name : RecvOpen()
+ *    Description   : open an IM context for client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvOpen (req)
+     XimRequestPacket *req;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  XIMID im_id;
+  int len;
+
+  if (_CheckLocaleName (req->data, cur_use_lang) == False)
+    return XIM_LocaleNotSupported;
+
+  if (!(im_id = CreateIM ()))
+    return XIM_BadAlloc;
+
+#ifdef DYNAMIC_EVENT_FLOW_MODEL
+  SendRegisterTriggerKeys (im_id);
+#endif /* DYNAMIC_EVENT_FLOW_MODEL */
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-id */
+    sizeof (CARD16) +           /* 2 byte length of IM attr. */
+    imattr_list_size +          /* n IM attr. supported */
+    sizeof (CARD16) +           /* 2 byte length of IC attr. */
+    sizeof (CARD16) +           /* 2 unused */
+    icattr_list_size;           /* m IC attr. supported */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_OPEN_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (imattr_list_size);
+  memcpy ((char *) &buf_16[2], (char *) imattr_list, imattr_list_size);
+
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD16) + sizeof (CARD16) + imattr_list_size);
+  buf_16[0] = GET_CARD16 (icattr_list_size);
+  memcpy ((char *) &buf_16[2], (char *) icattr_list, icattr_list_size);
+
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvClose()
+ *    Description   : close an IM client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvClose (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  XIMID im_id;
+  int len;
+
+  im_id = cur_im_id = GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (RemoveIMWithId (im_id) == False)
+    return XIM_BadProtocol;
+  cur_im_id = 0;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16);            /* 2 unused */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_CLOSE_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvQueryExtension()
+ *    Description   : send extension lists supported by server as the
+ *                    client asks.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvQueryExtension (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) (req->data);
+  CARD8 *reply;
+  XIMID im_id;
+  CARD8 value[BUFSIZ];
+  int len, value_len;
+  int ret, n;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    {
+      return XIM_BadProtocol;
+    }
+
+  /* get extetions supported by us. */
+  n = GET_CARD16 (buf_16[1]);   /* 2 n byte length */
+  ret = GetExtensionList ((CARD8 *) & buf_16[2], n, value, &value_len);
+  if (ret)
+    return ret;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 n byte length */
+    value_len;                  /* n LISTofEXT */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_QUERY_EXTENSION_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (value_len);
+  (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvEncodingNegotiation()
+ *    Description   : decide COMPOUND_TEXT as the result of encoding
+ *                    negotiation between IM client and server.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvEncodingNegotiation (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  XIMID im_id;
+  int len, n, index;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  /* we care only the index of COMPOUNT_TEXT */
+  n = GET_CARD16 (buf_16[1]);   /* 2 byte length */
+  index = GetCompoundTextIndex ((CARD8 *) & buf_16[2], n);
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 category of the encoding */
+    sizeof (CARD16) +           /* 2 index of the encoding */
+    sizeof (CARD16);            /* 2 unused */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_ENCODING_NEGOTIATION_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (XIM_Encoding_NameCategory);
+  buf_16[2] = GET_CARD16 (index);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendSetEventMask()
+ *    Description   : send XEvent mask to client which will foward any
+ *                    event to the server.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      <none>
+ */
+static void
+SendSetEventMask (im_id, ic_id)
+     XIMID im_id;
+     XICID ic_id;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int len;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (BITMASK32) +        /* 4 forw-event-mask */
+    sizeof (BITMASK32);         /* 4 sync-event-mask */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_SET_EVENT_MASK, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_32 = (CARD32 *) & buf_16[2];
+  buf_32[0] = (KeyPressMask | StructureNotifyMask);
+  buf_32[1] = (KeyPressMask | StructureNotifyMask);
+  (void) _WriteToClientFlush (reply, len);
+  FREE (reply);
+}
+
+/*
+ *    Function Name : RecvCreateIC()
+ *    Description   : create an IC for the connected client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvCreateIC (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+  int ret, len;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  /* create IC. */
+  len = (int) GET_CARD16 (buf_16[1]);
+  ret = CreateClientIC (im_id, (CARD8 *) & buf_16[2], len, &ic_id);
+  if (ret)
+    return ret;
+  cur_ic_id = ic_id;
+
+  /* reply */
+  ret = SendIdOnly (im_id, ic_id, XIM_CREATE_IC_REPLY, 0);
+  if (ret)
+    return ret;
+
+  SendSetEventMask (im_id, ic_id);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvSetICValues()
+ *    Description   : set IC values to internal client context.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvSetICValues (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+  int ret, n;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  n = (int) GET_CARD16 (buf_16[2]);     /* 2 n byte length */
+  ret = SetClientICValues ((CARD8 *) & buf_16[4], n, xc);
+  if (ret)
+    return ret;
+
+  /* reply */
+  return SendIdOnly (im_id, ic_id, XIM_SET_IC_VALUES_REPLY, 0);
+}
+
+/*
+ *    Function Name : RecvGetICValues()
+ *    Description   : encode IC values of client context, then send to client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvGetICValues (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  CARD8 value[BUFSIZ];
+  XIMID im_id;
+  XICID ic_id;
+  int len, value_len, n;
+  int ret;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  n = GET_CARD16 (buf_16[2]);
+  ret = EncodeICAttributes ((CARD8 *) & buf_16[3], n, xc, value, &value_len);
+  if (ret)
+    return ret;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (INT16) +            /* 2 byte length of ic-attr */
+    sizeof (CARD16) +           /* 2 unused */
+    value_len;                  /* n list of ic-attr */
+
+  /* reply */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_GET_IC_VALUES_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_16[2] = GET_CARD16 (value_len);
+  (void) memcpy ((char *) &buf_16[4], (char *) value, value_len);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : JWMline_get()
+ *    Description   : put preedit string into a common shared CT buffer which
+ *                    can be accessed by GET_COMMON_CT_BUFFER, i.e., "ct_buf". 
+ *    Parameter     :
+ *      base        : beginning position of preedit string.
+ *      pre_len_returned
+ *                  : returned length of the string got.
+ *    Returned Value:
+ *      <none>
+ */
+static void
+JWMline_get (base, pre_len_returned)
+     int base;
+     int *pre_len_returned;
+{
+  register XIMLangRec *xl;
+  register int wc_len, send_len;
+  register wchar *JW_buf;
+
+  *pre_len_returned = 0;
+  xl = cur_p->cur_xl;
+  JW_buf = xl->buf + base;
+  send_len = wc_len = xl->max_pos - base;
+  if (wc_len > 0)
+    {
+      while (1)
+        {
+          send_len = wchar_to_ct (cur_p->cur_xl->xlc, JW_buf, ct_buf, wc_len, ct_buf_max);
+          if (send_len < -1)
+            {
+              return;
+            }
+          else if (send_len == -1)
+            {
+              if (realloc_ct_buf () < 0)
+                return;
+            }
+          else
+            {
+              break;
+            }
+        }
+    }
+  *pre_len_returned = ((send_len >= 0) ? send_len : 0);
+}
+
+/*
+ *    Function Name : ResetClientIC()
+ *    Description   : reset IC context of client.
+ *    Parameter     :
+ *      xc          : pointer to client structure.
+ *      pre_str_filled
+ *                  : returned preedit string. 
+ *                    The pre_str_filled parameter is only for readability,
+ *                    it is used in a global variable "ct_buf".
+ *      pre_len_returned
+ *                  : length of preedit string 
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+ /*ARGSUSED*/ static int
+ResetClientIC (xc, pre_str_filled, pre_len_returned)
+     XIMClientRec *xc;
+     unsigned char *pre_str_filled;     /* only for readable ct_buf */
+     int *pre_len_returned;
+{
+  WnnClientRec *save_c_c;
+  XIMClientRec *save_cur_p, *save_cur_x;
+  int ret;
+
+  /* refer to util.c: ResetIC() */
+  {
+    save_c_c = c_c;
+    save_cur_p = cur_p;
+    save_cur_x = cur_x;
+    cur_x = xc;
+    if (IsPreeditNothing (xc))
+      {
+        cur_p = xc->root_pointer->ximclient;
+      }
+    else
+      {
+        cur_p = cur_x;
+      }
+    c_c = cur_p->cur_xl->w_c;
+    ret = reset_c_b ();
+    JWMline_get (0, pre_len_returned);
+    JWMline_clear (0);
+    c_c = save_c_c;
+    cur_p = save_cur_p;
+    cur_x = save_cur_x;
+    if (ret == -1)
+      return XIM_BadProtocol;
+  }
+  return 0;
+}
+
+/*
+ *    Function Name : RecvResetIC()
+ *    Description   : reset IC context as client asks.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvResetIC (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  XIMID im_id;
+  XICID ic_id;
+  int len, pre_len;
+  int ret;
+  unsigned char *pre_str;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  pre_str = GET_SHARED_CT_BUFFER ();
+  ret = ResetClientIC (xc, pre_str, &pre_len);
+  if (ret)
+    return ret;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (INT16) +            /* 2 byte length of string */
+    pre_len +                   /* n LISTofBYTE */
+    PAD (sizeof (INT16) + pre_len);     /* p Pad(2 + n) */
+
+  /* reply */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_RESET_IC_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_16[2] = GET_CARD16 (pre_len);
+  if (pre_len > 0)
+    (void) memcpy ((char *) &buf_16[3], (char *) pre_str, pre_len);
+
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvDestroyIC()
+ *    Description   : destroy an IC context.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvDestroyIC (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+  (void) destroy_client (xc);
+  cur_ic_id = 0;
+
+  /* reply */
+  return SendIdOnly (im_id, ic_id, XIM_DESTROY_IC_REPLY, 0);
+}
+
+/*
+ *    Function Name : SetClientICFocus()
+ *    Description   : set IC focus to the specified client.
+ *    Parameter     :
+ *      xc          : pointer to client structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SetClientICFocus (xc)
+     XIMClientRec *xc;
+{
+  register XIMInputRec *xi;
+  XIMClientRec *save_cur_p, *save_cur_x;
+  WnnClientRec *save_c_c;
+
+  /* modified from util.c: SetICFocus() */
+  {
+    for (xi = input_list; xi != NULL; xi = xi->next)
+      {
+        if (xi->w == xc->focus_window)
+          break;
+      }
+    if (xi == NULL)
+      {
+        if (!(xi = (XIMInputRec *) Malloc (sizeof (XIMInputRec))))
+          {
+            malloc_error ("allocation of Focus data struct");
+            return XIM_BadAlloc;
+          }
+        xi->w = xc->focus_window;
+        xi->pclient = xc;
+        xi->next = NULL;
+        add_inputlist (xi);
+      }
+    save_cur_p = cur_p;
+    save_cur_x = cur_x;
+    save_c_c = c_c;
+    cur_x = xc;
+    if (IsPreeditNothing (xc))
+      {
+        cur_p = xc->root_pointer->ximclient;
+      }
+    else
+      {
+        cur_p = cur_x;
+      }
+    c_c = cur_p->cur_xl->w_c;
+    cur_rk = c_c->rk;
+    cur_rk_table = cur_rk->rk_table;
+#ifdef  CALLBACKS
+    if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsStatusCallbacks (xc))
+      {
+#else /* CALLBACKS */
+    if (IsPreeditPosition (xc) || IsPreeditArea (xc))
+      {
+#endif /* CALLBACKS */
+        reset_preedit (xc);
+      }
+#ifdef  CALLBACKS
+    if (IsStatusArea (xc) || IsStatusCallbacks (xc))
+      {
+#else /* CALLBACKS */
+    if (IsStatusArea (xc))
+      {
+#endif /* CALLBACKS */
+        visual_status ();
+      }
+    cur_p = save_cur_p;
+    cur_x = save_cur_x;
+    c_c = save_c_c;
+    if (c_c)
+      {
+        cur_rk = c_c->rk;
+        cur_rk_table = cur_rk->rk_table;
+      }
+  }
+  return 0;
+}
+
+/*
+ *    Function Name : UnsetClientICFocus()
+ *    Description   : unset IC focus to the specified client.
+ *    Parameter     :
+ *      xc          : pointer to client structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+UnsetClientICFocus (xc)
+     XIMClientRec *xc;
+{
+  register XIMInputRec *xi;
+  XIMClientRec *save_cur_p, *save_cur_x;
+  WnnClientRec *save_c_c;
+
+  /* modified from util.c: UnsetICFocus() */
+  {
+    for (xi = input_list; xi != NULL; xi = xi->next)
+      {
+        if (xi->w == xc->focus_window)
+          break;
+      }
+    if (xi == NULL)
+      {
+        return XIM_BadFocusWindow;
+      }
+    else
+      {
+        remove_inputlist (xi);
+        if (cur_input == xi)
+          cur_input = 0;
+        Free ((char *) xi);
+        save_cur_p = cur_p;
+        save_cur_x = cur_x;
+        save_c_c = c_c;
+        cur_x = xc;
+        if (IsPreeditNothing (xc))
+          {
+            cur_p = xc->root_pointer->ximclient;
+          }
+        else
+          {
+            cur_p = cur_x;
+          }
+        c_c = cur_p->cur_xl->w_c;
+        cur_rk = c_c->rk;
+        cur_rk_table = cur_rk->rk_table;
+#ifdef  CALLBACKS
+        if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsPreeditCallbacks (xc))
+          {
+#else /* CALLBACKS */
+        if (IsPreeditPosition (xc) || IsPreeditArea (xc))
+          {
+#endif /* CALLBACKS */
+            invisual_window ();
+          }
+#ifdef  CALLBACKS
+        if (IsStatusArea (xc) || IsStatusCallbacks (xc))
+          {
+#else /* CALLBACKS */
+        if (IsStatusArea (xc))
+          {
+#endif /* CALLBACKS */
+            invisual_status ();
+          }
+        cur_p = save_cur_p;
+        cur_x = save_cur_x;
+        c_c = save_c_c;
+        if (c_c)
+          {
+            cur_rk = c_c->rk;
+            cur_rk_table = cur_rk->rk_table;
+          }
+      }
+  }
+  return 0;
+}
+
+/*
+ *    Function Name : RecvSetICFocus()
+ *    Description   : set IC focus. 
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvSetICFocus (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  return SetClientICFocus (xc);
+
+  /* asynchoronous request, no reply */
+}
+
+/*
+ *    Function Name : RecvUnsetICFocus()
+ *    Description   : unset IC focus.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvUnsetICFocus (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  return UnsetClientICFocus (xc);
+
+  /* asynchoronous request, no reply */
+}
+
+/*
+ *    Function Name : RecvGetIMValues()
+ *    Description   : encode IM values to byte data, then send it to client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvGetIMValues (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  XIMID im_id;
+  CARD8 value[BUFSIZ];
+  int len, value_len, n;
+  int ret;
+  XIMContextRec *im;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!(im = GetIMWithId (im_id)))
+    return XIM_BadProtocol;
+
+  n = GET_CARD16 (buf_16[1]);
+  ret = EncodeIMAttributes ((CARD8 *) & buf_16[2], n, im, value, &value_len);
+  if (ret)
+    return ret;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (INT16) +            /* 2 byte length of im-attr */
+    value_len;                  /* n list of im-attr */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_GET_IM_VALUES_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (value_len);
+  (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvSetIMValues()
+ *    Description   : decode IM values, then send it to client context.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvSetIMValues (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  CARD8 *reply;
+  XIMID im_id;
+  int len, n;
+  int ret;
+  XIMContextRec *im;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!(im = GetIMWithId (im_id)))
+    return XIM_BadProtocol;
+
+  n = (int) GET_CARD16 (buf_16[1]);     /* 2 n byte length */
+  ret = SetClientIMValues ((CARD8 *) & buf_16[2], n, im);
+  if (ret)
+    return ret;
+
+  /* reply */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16);            /* 2 unused */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_SET_IM_VALUES_REPLY, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendCommit()
+ *    Description   : commit a string to client, the string is converted
+ *                    by input method, such kanji, and is encoded in CT.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      flag        : flag of XimLookupKeySym, XimLookupChars or both.
+ *      keysym      : keysym if committed.
+ *      ct_str      : CT string if committed.
+ *      ct_len      : length of string.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendCommit (im_id, ic_id, flag, keysym, ct_str, ct_len)
+     XIMID im_id;
+     XICID ic_id;
+     int flag;
+     KeySym keysym;
+     char *ct_str;
+     int ct_len;
+{
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  CARD8 *reply;
+  int len;
+
+  XIMClientRec *xc;
+
+  if (!(xc = GetICWithId (ic_id)) || xc->im_id != im_id)
+    return XIM_BadProtocol;
+
+  flag |= XimSYNCHRONUS;        /* ask sync */
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-id */
+    sizeof (CARD16) +           /* 2 input-context-id */
+    sizeof (BITMASK16) +        /* 2 flag */
+    LENGTH_KEYSYM (flag, sizeof (CARD32)) +     /* 2+6 KeySym */
+    LENGTH_STRING_WITH_FLAG (flag, ct_len);     /* 2+n+Pad(2+n) string */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_COMMIT, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_16[2] = GET_CARD16 (flag);
+  buf_16 = (CARD16 *) & buf_16[3];
+  if (flag & XimLookupKeySym)
+    {
+      buf_32 = (CARD32 *) & buf_16[1];
+      buf_32[0] = GET_CARD32 (keysym);
+      buf_16 = (CARD16 *) & buf_32[1];
+    }
+  if (flag & XimLookupChars)
+    {
+      buf_16[0] = GET_CARD16 (ct_len);
+      (void) memcpy ((char *) &buf_16[1], ct_str, ct_len);
+    }
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+
+  if (ClientSyncDone (xc) == True)
+    return SendSyncReply (im_id, ic_id);
+  else
+    return 0;
+}
+
+/*
+ *    Function Name : SendForwardEvent()
+ *    Description   : usually it is to send event back to client, e.g.
+ *                    when no filter in server.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      serial      : serial number of event.
+ *      event       : pointer to XEvent.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendForwardEvent (im_id, ic_id, serial, event)
+     XIMID im_id;
+     XICID ic_id;
+     int serial;
+     XEvent *event;
+{
+  CARD16 *buf_16;
+  CARD8 *reply;
+  int len;
+  int flag;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (BITMASK16) +        /* 2 flag */
+    sizeof (CARD16) +           /* 2 serial number */
+    sizeof (xEvent);            /* n XEVENT */
+
+  flag = 0;                     /* no sync flag */
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_FORWARD_EVENT, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_16[2] = GET_CARD16 (flag);
+  buf_16[3] = GET_CARD16 (serial);
+  if (_XimEventToWire (event, (xEvent *) & buf_16[4]) == False)
+    return XIM_BadSomething;
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : ExecInputMethod()
+ *    Description   : execute input method to do some henkan (conversion).
+ *                    This is referred to keyin.c: RequestDispatch() on
+ *                    the case of XIM_Event.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      xevp        : pointer to event.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+ExecInputMethod (im_id, ic_id, xevp)
+     XIMID im_id;
+     XICID ic_id;
+     XEvent *xevp;
+{
+  int buff[32], in;
+  int ret;
+  register int i, n_bytes;
+
+  ret = key_input (buff, xevp);
+  if (ret == 0)
+    {
+      /* send_nofilter() */
+      return xim_send_nofilter ();
+    }
+  else if (ret > 0)
+    {
+      for (i = 0; i < ret;)
+        {
+          n_bytes = get_cswidth_by_char (in = buff[i++]);
+          for (; n_bytes > 1 && i < ret; n_bytes--, i++)
+            {
+              in = (in << 8) + buff[i];
+            }
+          in_put (in);
+        }
+    }
+  return 0;
+}
+
+/*
+ *    Function Name : RecvForwardEvent()
+ *    Description   : filter event forwarded by client to execute input
+ *                    method.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvForwardEvent (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+  int ret;
+  int flag, serial;
+  XEvent event;
+
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  flag = (int) GET_CARD16 (buf_16[2]);
+  serial = (int) GET_CARD16 (buf_16[3]);
+
+  SetClientSync (xc, True);
+
+  if (_XimWireToEvent (dpy, serial, (xEvent *) & buf_16[4], &event) == False)
+    return XIM_BadProtocol;
+  /*
+   * save event which will back to client if no filter.
+   */
+  (void) memcpy ((char *) &(xc->cur_event), (char *) &event, sizeof (XEvent));
+
+  ret = ExecInputMethod (im_id, ic_id, &event);
+  /*
+   * if it is async (no XimSYNCHRONUS), force 0 returned, so no anything
+   * even no error is sent to client.
+   */
+  if (ret)
+    return ((flag & XimSYNCHRONUS) ? ret : 0);
+
+  if (ClientSyncDone (xc) == True)
+    return SendSyncReply (im_id, ic_id);
+  else
+    return 0;
+}
+
+/*
+ *    Function Name : RecvStrConversionReply()
+ *    Description   : send a request that is the format of:
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvStrConversionReply (req)
+     XimRequestPacket *req;
+{
+  /* don't care in this model. */
+  return 0;
+}
+
+#ifdef CALLBACKS
+
+/*
+ *    Function Name : CopyText()
+ *    Description   : copy string and feedback array to byte data
+ *    Parameter     :
+ *      bur         : pointer to the byte data.
+ *      str         : string
+ *      feedback    : array of feedback.
+ *      feedback_num: number of feedback.
+ *    Returned Value:
+ *      <none>
+ */
+static void
+CopyText (buf, str, str_len, feedback, feedback_num)
+     CARD8 *buf;
+     char *str;
+     int str_len;
+     XIMFeedback *feedback;
+     int feedback_num;
+{
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  CARD32 *save_32;
+  BITMASK32 status = 0;
+  int i;
+
+  save_32 = (CARD32 *) buf;
+  buf_16 = (CARD16 *) & save_32[1];
+  if (str_len > 0)
+    {
+      buf_16[0] = GET_CARD16 (str_len);
+      (void) strncpy ((char *) &buf_16[1], str, str_len);
+      buf_16 = (CARD16 *) ((CARD8 *) buf_16 + sizeof (CARD16) + PAD (sizeof (CARD16) + str_len));
+    }
+  else
+    {
+      status |= XIMNoString;
+    }
+  if (feedback_num > 0)
+    {
+      buf_16[0] = GET_CARD16 (feedback_num);
+      buf_32 = (CARD32 *) & buf_16[2];
+      for (i = 0; i < feedback_num; i++)
+        {
+          buf_32[i] = GET_CARD32 (feedback[i]);
+        }
+    }
+  else
+    {
+      status |= XIMNoFeedback;
+    }
+  save_32[0] = GET_CARD32 (status);
+}
+
+/*
+ *    Function Name : SendPreeditDraw()
+ *    Description   : send the request of XIM_PREEDT_DRAW.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      caret       : caret
+ *      chg_first   : first of change.
+ *      chg_len     : length of change.
+ *      str         : string.
+ *      str_len     : length of string.
+ *      feedback    : array of feedback.
+ *      feedback_num: number of feedback.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendPreeditDraw (im_id, ic_id, caret, chg_first, chg_len, str, str_len, feedback, feedback_num)
+     XIMID im_id;
+     XICID ic_id;
+     INT32 caret;
+     INT32 chg_first;
+     INT32 chg_len;
+     char *str;
+     int str_len;
+     XIMFeedback *feedback;
+     int feedback_num;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int len;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (INT32) +            /* 4 caret */
+    sizeof (INT32) +            /* 4 chg_first */
+    sizeof (INT32) +            /* 4 chg_length */
+    sizeof (BITMASK32) +        /* 4 status */
+    LENGTH_STRING (str_len) +   /* x string */
+    LENGTH_FEEDBACK (feedback_num);     /* x feedback array */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_PREEDIT_DRAW, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_32 = (CARD32 *) & buf_16[2];
+  buf_32[0] = GET_CARD32 (caret);
+  buf_32[1] = GET_CARD32 (chg_first);
+  buf_32[2] = GET_CARD32 (chg_len);
+  buf_16 = (CARD16 *) & buf_32[3];
+  CopyText ((CARD8 *) & buf_32[3], str, str_len, feedback, feedback_num);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendPreeditCaret()
+ *    Description   : send the request of XIM_PREEDIT_CARET.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      pos         : position
+ *      direct      : direction of caret.
+ *      style       : style of caret.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendPreeditCaret (im_id, ic_id, pos, direct, style)
+     XIMID im_id;
+     XICID ic_id;
+     INT32 pos;
+     CARD32 direct;
+     CARD32 style;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int len;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (INT32) +            /* 4 position */
+    sizeof (CARD32) +           /* 4 direction */
+    sizeof (CARD32);            /* 4 style */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_PREEDIT_CARET, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_32 = (CARD32 *) & buf_16[2];
+  buf_32[0] = GET_CARD32 (pos);
+  buf_32[1] = GET_CARD32 (direct);
+  buf_32[2] = GET_CARD32 (style);
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : SendStatusDraw()
+ *    Description   : send the request of XIM_STATUS_DRAW.
+ *    Parameter     :
+ *      im_id       : client input-method-id.
+ *      ic_id       : client input-context-id.
+ *      st_type     : type of status.
+ *      str         : string.
+ *      str_len     : length of string.
+ *      feedback    : array of feedback.
+ *      feedback_num: number of feedback.
+ *      pixmap      : pixmap data. 
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+SendStatusDraw (im_id, ic_id, st_type, str, str_len, feedback, feedback_num, pixmap)
+     XIMID im_id;
+     XICID ic_id;
+     CARD32 st_type;
+     char *str;
+     int str_len;
+     XIMFeedback *feedback;
+     int feedback_num;
+     PIXMAP pixmap;
+{
+  CARD8 *reply;
+  CARD16 *buf_16;
+  CARD32 *buf_32;
+  int len;
+
+  /* send */
+  len = sizeof (CARD16) +       /* 2 input-method-ID */
+    sizeof (CARD16) +           /* 2 input-context-ID */
+    sizeof (CARD32) +           /* 4 type */
+    sizeof (BITMASK32) +        /* 4 status */
+    LENGTH_TEXT (st_type, str_len, feedback_num) +      /* text */
+    LENGTH_PIXMAP (st_type);    /* x pixmap */
+
+  reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
+  len += AddHead (reply, XIM_STATUS_DRAW, 0, len);
+  buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
+  buf_16[0] = GET_CARD16 (im_id);
+  buf_16[1] = GET_CARD16 (ic_id);
+  buf_32 = (CARD32 *) & buf_16[2];
+  buf_32[0] = GET_CARD32 (st_type);
+  if (st_type == XIMTextType)
+    {
+      CopyText ((CARD8 *) & buf_32[1], str, str_len, feedback, feedback_num);
+    }
+  else
+    {
+      buf_32[1] = GET_CARD32 (pixmap);
+    }
+  if (_WriteToClientFlush (reply, len) < 0)
+    {
+      FREE (reply);
+      return XIM_BadSomething;
+    }
+  FREE (reply);
+  return 0;
+}
+
+/*
+ *    Function Name : RecvPreeditStartReply()
+ *    Description   : receive a reply from client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvPreeditStartReply (req)
+     XimRequestPacket *req;
+{
+  /* don't care. */
+  return 0;
+}
+
+/*
+ *    Function Name : RecvPreeditCaretReply()
+ *    Description   : receive a reply from client.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+static int
+RecvPreeditCaretReply (req)
+     XimRequestPacket *req;
+{
+  /* don't care. */
+  return 0;
+}
+
+#endif /* CALLBACKS */
+
+#if defined(EXT_MOVE) || defined(SPOT)
+
+/*
+ *    Function Name : RecvExtMove()
+ *    Description   : change only the point of spot.
+ *    Parameter     :
+ *      req         : pointer to a request structure.
+ *    Returned Value:
+ *      <none>
+ */
+static int
+RecvExtMove (req)
+     XimRequestPacket *req;
+{
+  CARD16 *buf_16 = (CARD16 *) req->data;
+  XIMID im_id;
+  XICID ic_id;
+  short x, y;
+  XIMClientRec *xc;
+
+  im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
+  if (!GetIMWithId (im_id))
+    return XIM_BadProtocol;
+
+  ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
+  if (!(xc = GetICWithId (ic_id)))
+    return XIM_BadProtocol;
+
+  x = (short) GET_CARD16 (buf_16[2]);
+  y = (short) GET_CARD16 (buf_16[3]);
+  if (change_spotlocation (xc, x, y) != 0)
+    return XIM_BadSpotLocation;
+  else
+    return 0;
+
+  /* asynchoronous request, no reply */
+}
+
+#endif /* defined(EXT_MOVE) || defined(SPOT) */
+
+/*
+ *    Function Name : AppendServerToProperty()
+ *    Description   : append server id to IM_SERVERS property.
+ *                    Don't use PropModeAppend that will propagate a same
+ *                    server id more and more in the property.
+ *    Parameter     :
+ *      disp        : pointer to X display.
+ *      win         : window that holds the property.
+ *      imserver    : our server id to be appended.
+ *    Returned Value:
+ *      True        : success.
+ *      False       : error.
+ */
+static Bool
+AppendServerToProperty (disp, win, imserver)
+     Display *disp;
+     Window win;
+     Atom imserver;
+{
+  Atom server_atom, actual_type;
+  Atom *atom_list, *new_list;
+  int actual_format;
+  unsigned long nitems, bytes_after;
+  unsigned char *prop_return;
+  int i;
+
+  server_atom = XInternAtom (disp, XIM_SERVERS, False);
+  (void) XGetWindowProperty (disp, win, server_atom, 0L, 1000000L, False, XA_ATOM, &actual_type, &actual_format, &nitems, &bytes_after, &prop_return);
+
+  if (nitems > 0 && (actual_type != XA_ATOM || actual_format != 32))
+    {
+      return False;
+    }
+  if (nitems > 0)
+    {
+      /*
+       * search whether our server id has been registered or not.
+       */
+      atom_list = (Atom *) prop_return;
+      for (i = 0; i < nitems; i++)
+        {
+          if (atom_list[i] == imserver)
+            return True;
+        }
+      new_list = (Atom *) Malloc ((nitems + 1) * sizeof (Atom));
+      if (!new_list)
+        {
+          malloc_error ("no memory for atom list.");
+          return False;
+        }
+      (void) memcpy ((char *) new_list, (char *) prop_return, nitems * sizeof (Atom));
+      new_list[nitems] = imserver;
+    }
+  else
+    {
+      new_list = &imserver;
+    }
+
+  /*
+   * append our server id to IM_SERVERS property.
+   */
+  XChangeProperty (disp, win, server_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *) new_list, (nitems + 1));
+  if (nitems > 0)
+    {
+      XFree ((char *) prop_return);
+      XFree ((char *) new_list);
+    }
+  return True;
+}
+
+/*--------------------------------------------------------------------*
+ *                                                                    *
+ *                         Public Functions                           *
+ *                                                                    *
+ *--------------------------------------------------------------------*/
+
+/*
+ *    Function Name : XimError()
+ *    Description   : take the breakpoint of error when it occurs at any time.
+ *    Parameter     :
+ *      fd          : socket id of IM client.
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+XimError (int fd)
+#else
+void
+XimError (fd)
+     int fd;
+#endif /* NeedFunctionPrototypes */
+{
+  register XIMClientRec *xc;
+
+  for (xc = ximclient_list; xc != NULL; xc = xc->next)
+    {
+      if (xc->fd == fd)
+        {
+          (void) RemoveIMWithId ((XIMID) xc->im_id);
+        }
+    }
+}
+
+/*
+ *    Function Name : XimRequestDispatch()
+ *    Description   : dispatch all requests of X11 IM protocol.
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+XimRequestDispatch (void)
+#else
+void
+XimRequestDispatch ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  XimRequestPacket req_data;
+  XimRequestPacket *req = &req_data;
+  int ret;
+
+  ret = cur_status = 0;
+  if (RecvRequest (req) < 0)
+    return;
+
+  /* respond each request of protocol */
+  switch (req->major_opcode)
+    {
+    case XIM_AUTH_NEXT:
+      ret = SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
+      break;
+    case XIM_AUTH_REPLY:
+      ret = SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
+      break;
+    case XIM_CONNECT:
+      ret = RecvConnect (req);
+      break;
+    case XIM_DISCONNECT:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvDisconnect (req);
+      break;
+    case XIM_OPEN:
+      cur_status = XIM_IMID_VALID;
+      ret = RecvOpen (req);
+      break;
+    case XIM_CLOSE:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvClose (req);
+      break;
+    case XIM_ENCODING_NEGOTIATION:
+      cur_status = XIM_IMID_VALID;
+      ret = RecvEncodingNegotiation (req);
+      break;
+    case XIM_QUERY_EXTENSION:
+      cur_status = XIM_IMID_VALID;
+      ret = RecvQueryExtension (req);
+      break;
+    case XIM_SET_IM_VALUES:
+      cur_status = XIM_IMID_VALID;
+      ret = RecvSetIMValues (req);
+      break;
+    case XIM_GET_IM_VALUES:
+      cur_status = XIM_IMID_VALID;
+      ret = RecvGetIMValues (req);
+      break;
+    case XIM_CREATE_IC:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvCreateIC (req);
+      break;
+    case XIM_DESTROY_IC:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvDestroyIC (req);
+      break;
+    case XIM_SET_IC_VALUES:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvSetICValues (req);
+      break;
+    case XIM_GET_IC_VALUES:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvGetICValues (req);
+      break;
+    case XIM_SET_IC_FOCUS:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      (void) RecvSetICFocus (req);      /* asyncronous request */
+      break;
+    case XIM_UNSET_IC_FOCUS:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      (void) RecvUnsetICFocus (req);    /* asyncronous request */
+      break;
+    case XIM_TRIGGER_NOTIFY:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+#ifdef DYNAMIC_EVENT_FLOW_MODEL
+      ret = RecvTriggerNotify (req);
+#else
+      ret = 0;
+#endif /* DYNAMIC_EVENT_FLOW_MODEL */
+      break;
+    case XIM_FORWARD_EVENT:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvForwardEvent (req);
+      break;
+    case XIM_RESET_IC:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvResetIC (req);
+      break;
+    case XIM_SYNC:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvSync (req);
+      break;
+    case XIM_SYNC_REPLY:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      (void) RecvSyncReply (req);       /* don't need send anything */
+      break;
+#ifdef CALLBACKS
+    case XIM_PREEDIT_START_REPLY:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvPreeditStartReply (req);
+      break;
+    case XIM_PREEDIT_CARET_REPLY:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvPreeditCaretReply (req);
+      break;
+#endif /* CALLBACKS */
+    case XIM_STR_CONVERSION_REPLY:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      ret = RecvStrConversionReply (req);
+      break;
+#if defined(EXT_MOVE) || defined(SPOT)
+    case XIM_EXT_MOVE:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      (void) RecvExtMove (req); /* asyncronous request */
+      break;
+#endif /* defined(EXT_MOVE) || defined(SPOT) */
+    case XIM_ERROR:
+      cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
+      (void) RecvError (req);   /* asyncronous request */
+      break;
+    default:
+      ret = XIM_BadProtocol;
+    }
+  if (ret)
+    SendError (ret);
+  FREE (req->data);
+}
+
+/*
+ *    Function Name : XimPreConnect()
+ *    Description   : make a base for preconnection with IM client. This
+ *                    includes to create all selection atoms, names and
+ *                    properties, plus some initial steps.
+ *    Parameter     :
+ *      port        : TCP/IP port number used in this IM protocol.
+ *      root        : default root client.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      = -1        : error, failed to make preconnection.
+ */
+#if NeedFunctionPrototypes
+int
+XimPreConnect (unsigned short port,     /* port number 38036/tcp of xwnmo */
+               XIMRootRec * root)
+#else
+int
+XimPreConnect (port, root)
+     unsigned short port;       /* port number 38036/tcp of xwnmo */
+     XIMRootRec *root;
+#endif /* NeedFunctionPrototypes */
+{
+  char atom_name[BUFFER_MAX];
+  char hostname[BUFFER_MAX];
+  int len;
+
+  /*
+   * make server atom:  @server=xwnmo
+   */
+  (void) sprintf (atom_name, "%s%s", XIM_SERVER_CATEGORY, XIM_SERVER_NAME);
+  if ((server_id = XInternAtom (dpy, atom_name, True)) != (Atom) None)
+    {
+      if (XGetSelectionOwner (dpy, server_id) != (Window) None)
+        {
+          print_out ("Another server has been already running.");
+          return -1;
+        }
+    }
+  else
+    {
+      server_id = XInternAtom (dpy, atom_name, False);
+    }
+
+  if (AppendServerToProperty (dpy, root->root_window, server_id) == False)
+    return -1;
+
+  /*
+   * make target XIM_LOCALES:  "@locale=ja,ja_JP,..."
+   */
+  (void) strcpy (atom_name, XIM_LOCAL_CATEGORY);
+  locale_supported = (unsigned char *) GetLocaleSupported ();
+  len = strlen (atom_name);
+  if (!(locale_prop = (unsigned char *) Malloc (len + strlen (locale_supported) + 1)))
+    {
+      malloc_error ("allocation of locale property");
+      return -1;
+    }
+  locale_target = XInternAtom (dpy, XIM_LOCALES, False);
+  (void) strcpy (locale_prop, atom_name);
+  (void) strcat (locale_prop, locale_supported);
+  locale_supported = locale_prop + len;
+
+  /*
+   * make target XIM_TRANSPORT:  "tcp/hostname:port"
+   */
+  (void) XmuGetHostname (hostname, (sizeof hostname));
+  (void) sprintf (atom_name, "%stcp/%s:%u", XIM_TRANSPORT_CATEGORY, hostname, port);
+  len = strlen (atom_name);
+  if (!(transport_prop = (unsigned char *) Malloc (len + 1)))
+    {
+      malloc_error ("allocation of transport property");
+      return -1;
+    }
+  transport_target = XInternAtom (dpy, XIM_TRANSPORT, False);
+  (void) strcpy (transport_prop, atom_name);
+
+  XSetSelectionOwner (dpy, server_id, root->ximclient->w, 0L);
+
+  InitiateProtocol ();
+
+  return 0;
+}
+
+/*
+ *    Function Name : XimConvertTarget()
+ *    Description   : convert a selection target and send its property
+ *                    to client.  This is in preconnection phase.
+ *    Parameter     :
+ *      dpy         : pointer to X display.
+ *      event       : selection event.
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+XimConvertTarget (Display * dpy, XSelectionRequestEvent * event)
+#else
+void
+XimConvertTarget (dpy, event)
+     Display *dpy;
+     XSelectionRequestEvent *event;
+#endif /* NeedFunctionPrototypes */
+{
+  XSelectionEvent new;
+  unsigned char *string = (unsigned char *) NULL;
+
+  bzero (&new, sizeof (XSelectionEvent));
+  new.type = SelectionNotify;
+  new.serial = event->serial;
+  new.display = event->display;
+  new.requestor = event->requestor;
+  new.selection = event->selection;
+  new.target = event->target;
+  new.time = event->time;
+  new.property = event->property;
+
+  if (event->selection == server_id)
+    {
+      if (event->target == locale_target)
+        string = locale_prop;
+      else if (event->target == transport_target)
+        string = transport_prop;
+      if (string)
+        {
+          XChangeProperty (dpy, event->requestor, event->property, event->target, 8, PropModeReplace, string, strlen ((char *) string));
+          XFlush (dpy);
+        }
+    }
+  XSendEvent (dpy, event->requestor, False, NoEventMask, (XEvent *) & new);
+}
+
+/*
+ *    Function Name : xim_send_ct()
+ *    Description   : similar to Xsi IM send_ct().
+ *    Parameter     :
+ *      ct          : CT string
+ *      ct_len      : length of string in byte.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+#if NeedFunctionPrototypes
+int
+xim_send_ct (register char *ct, register int ct_len)
+#else
+int
+xim_send_ct (ct, ct_len)
+     register char *ct;
+     register int ct_len;
+#endif /* NeedFunctionPrototypes */
+{
+  return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupChars, (KeySym) 0, ct, ct_len);
+}
+
+/*
+ *    Function Name : xim_send_keysym()
+ *    Description   : similar to Xsi IM send_keysym().
+ *    Parameter     :
+ *      keysym      : keysym code
+ *      str         : keysym character.
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+#if NeedFunctionPrototypes
+int
+xim_send_keysym (KeySym keysym, char str)
+#else
+int
+xim_send_keysym (keysym, str)
+     KeySym keysym;
+     char str;
+#endif /* NeedFunctionPrototypes */
+{
+  if (keysym < 0x20)
+    {
+      keysym |= 0xff00;
+      return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupKeySym, keysym, (char *) NULL, 0);
+    }
+  else
+    {
+      str &= 0xff;
+      return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupBoth, keysym, &str, 1);
+    }
+}
+
+/*
+ *    Function Name : xim_send_nofilter()
+ *    Description   : similar to Xsi IM send_nofilter().
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      = 0         : successed.
+ *      > 0         : error, the number is error code.
+ */
+#if NeedFunctionPrototypes
+int
+xim_send_nofilter (void)
+#else
+int
+xim_send_nofilter ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  XEvent *xev = CUR_CLIENT_EVENT ();
+  int serial = XIM_SERIALNUMBER (((XAnyEvent *) xev)->serial);
+
+  return SendForwardEvent (CUR_IM_ID (), CUR_IC_ID (), serial, xev);
+}
+
+#ifdef CALLBACKS
+
+/*
+ *    Function Name : xim_send_preeditstart()
+ *    Description   : similar to Xsi IM send_preeditstart().
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_preeditstart (void)
+#else
+void
+xim_send_preeditstart ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_START, 0);
+}
+
+/*
+ *    Function Name : xim_send_preeditdraw()
+ *    Description   : similar to Xsi IM send_preeditdraw().
+ *    Parameter     :
+ *      caret       : caret
+ *      first       : first of change.
+ *      chg_len     : length of change.
+ *      str         : wchar string.
+ *      len         : length of string in wchar.
+ *      flg         : flag
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_preeditdraw (int caret, int first, int chg_len, wchar * str, int len, int flg)
+#else
+void
+xim_send_preeditdraw (caret, first, chg_len, str, len, flg)
+     int caret;
+     int first;
+     int chg_len;
+     wchar *str;
+     int len;
+     int flg;
+#endif /* NeedFunctionPrototypes */
+{
+  unsigned short fb = 0;
+  int send_len;
+  XIMFeedback xim_fb;
+
+  if (str)
+    {
+      while (1)
+        {
+          send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
+          if (send_len < -1)
+            {
+              return;
+            }
+          else if (send_len == -1)
+            {
+              if (realloc_ct_buf () < 0)
+                return;
+            }
+          else
+            {
+              break;
+            }
+        }
+    }
+  else
+    {
+      send_len = 0;
+    }
+  if (flg & REV_FLAG)
+    fb |= XIMReverse;
+  if (flg & UNDER_FLAG)
+    fb |= XIMUnderline;
+  if (flg & BOLD_FLAG)
+    fb |= XIMHighlight;
+
+  xim_fb = (XIMFeedback) fb;
+  (void) SendPreeditDraw (CUR_IM_ID (), CUR_IC_ID (), caret, first, chg_len, ct_buf, send_len, (XIMFeedback *) & xim_fb, 1);
+}
+
+/*
+ *    Function Name : xim_send_preeditcaret()
+ *    Description   : similar to Xsi IM send_preeditcaret().
+ *    Parameter     :
+ *      pos         : position
+ *      flg         : flag
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_preeditcaret (int flg, int pos)
+#else
+void
+xim_send_preeditcaret (flg, pos)
+     int flg;
+     int pos;
+#endif /* NeedFunctionPrototypes */
+{
+  int style;
+
+  if (flg)
+    {
+      style = XIMIsPrimary;
+    }
+  else
+    {
+      style = XIMIsInvisible;
+    }
+  (void) SendPreeditCaret (CUR_IM_ID (), CUR_IC_ID (), pos, XIMAbsolutePosition, style);
+}
+
+/*
+ *    Function Name : xim_send_preeditdone()
+ *    Description   : similar to Xsi IM send_preeditdone().
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_preeditdone (void)
+#else
+void
+xim_send_preeditdone ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_DONE, 0);
+}
+
+/*
+ *    Function Name : xim_send_statusstart()
+ *    Description   : similar to Xsi IM send_statusstart().
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_statusstart (void)
+#else
+void
+xim_send_statusstart ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_START, 0);
+}
+
+/*
+ *    Function Name : xim_send_statusdraw()
+ *    Description   : similar to Xsi IM send_statusdraw().
+ *    Parameter     :
+ *      str         : wchar string.
+ *      len         : length of string in wchar.
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_statusdraw (wchar * str, int len)
+#else
+void
+xim_send_statusdraw (str, len)
+     wchar *str;
+     int len;
+#endif /* NeedFunctionPrototypes */
+{
+  int send_len;
+
+  /* refer to callback.c: send_statusdraw() */
+  while (1)
+    {
+      send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
+      if (send_len < -1)
+        {
+          return;
+        }
+      else if (send_len == -1)
+        {
+          if (realloc_ct_buf () < 0)
+            return;
+        }
+      else
+        {
+          break;
+        }
+    }
+  (void) SendStatusDraw (CUR_IM_ID (), CUR_IC_ID (), XIMTextType, ct_buf, send_len, (XIMFeedback *) NULL, 0, (PIXMAP) 0);
+}
+
+/*
+ *    Function Name : xim_send_statusdone()
+ *    Description   : similar to Xsi IM send_statusdone().
+ *    Parameter     :
+ *      <none>
+ *    Returned Value:
+ *      <none>
+ */
+#if NeedFunctionPrototypes
+void
+xim_send_statusdone (void)
+#else
+void
+xim_send_statusdone ()
+#endif                          /* NeedFunctionPrototypes */
+{
+  (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_DONE, 0);
+}
+
+#endif /* CALLBACKS */
+
+#endif /* !X11R5 */