1 /*
2  * $Id: ximdispt.c,v 1.2 2001/06/14 18:16:18 ura Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10  *
11  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with GNU Emacs; see the file COPYING.  If not, write to the
25  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  *
27  * Commentary:
28  *
29  * Change log:
30  *
31  * Last modified date: 8,Feb.1999
32  *
33  * Code:
34  *
35  */
36 
37 /*
38  *    Author Name         : Li Yuhong
39  *    File Name           : XimDispt.c
40  *    Module Description  : This module is to be corresponding to all
41  *                          protocol requests of X11R6 IM Version 1.0.
42  *    Modification History:
43  *      Jul 1, 1994       : initial version.
44  */
45 #ifndef X11R5
46 #include <stdio.h>
47 #include <X11/Xlib.h>
48 #ifndef NEED_EVENTS
49 #define NEED_EVENTS
50 #include <X11/Xproto.h>         /* for xEvent */
51 #undef NEED_EVENTS
52 #endif /* !NEED_EVENTS */
53 #include "XIMproto.h"           /* for ximICValuesReq... */
54 #include "Ximprot.h"
55 #include "sdefine.h"
56 #include "xim.h"
57 #include "sheader.h"
58 #include "ext.h"
59 
60 /*--------------------------------------------------------------------*
61  *                                                                    *
62  *                         Definition of Constant                     *
63  *                                                                    *
64  *--------------------------------------------------------------------*/
65 
66 /*
67  * name of "@im" modifier, which is compatible with R5.  The reasonable name
68  * might be "xwnmo".
69  */
70 #define XIM_SERVER_NAME         "_XWNMO"
71 
72 #define BASE_IM_ID              0       /* valid XIMID > 0 */
73 #define BUFFER_MAX              128
74 
75 #define ICPreeditAttributes     28      /* ic attr id. */
76 #define ICStatusAttributes      29
77 #define ICSeparatorOfNestedList 30
78 
79 #define XIM_EXT_SET_EVENT_MASK  128     /* extension must be >= 128 */
80 #if defined(EXT_MOVE) || defined(SPOT)  /* SPOT is name in Xsi R5 */
81 #define XIM_EXT_MOVE            130
82 #endif /* defined(EXT_MOVE) || defined(SPOT) */
83 
84 #define NO_NEST                 (XIMAttrList)NULL
85 #define END_OF_XIMATTRLIST      {0, 0, (char *)NULL, ((XIMAttrList)NULL)}
86 
87 #define XIMNoString             (1L)
88 #define XIMNoFeedback           (2L)
89 
90 
91 /*--------------------------------------------------------------------*
92  *                                                                    *
93  *                         Definition of Local Data Type              *
94  *                                                                    *
95  *--------------------------------------------------------------------*/
96 
97 #define PIXMAP  CARD32          /* for CALLBACKS only */
98 
99 /*
100  * XIM attribute structure for both IM and IC value.
101  */
102 typedef struct _XIMAttrRec
103 {
104   CARD16 attr_id;               /* attr id */
105   CARD16 type;                  /* type of attr */
106   char *name;                   /* name of attr */
107   struct _XIMAttrRec *nest;     /* nested list */
108 }
109 XIMAttrRec, *XIMAttrList;
110 
111 /*
112  * XIM client structure connected to this server.
113  */
114 typedef struct _XIMContextRec
115 {
116   XIMID im_id;                  /* IM id */
117   struct _XIMContextRec *next;  /* next of client */
118 }
119 XIMContextRec, *XIMContextList;
120 
121 /*
122  * extension.
123  */
124 typedef struct
125 {
126   char *name;                   /* ext name */
127   CARD8 major_code;             /* ext major opcode */
128   CARD8 minor_code;             /* ext minor opcode */
129 }
130 XIMQueryExtRec;
131 
132 #ifdef DYNAMIC_EVENT_FLOW_MODEL
133 /*
134  * just example for Dynamic Event Flow Model.
135  */
136 typedef struct
137 {
138   KeySym key;
139   KeySym modifier;
140   unsinged long modifier_mask;
141 }
142 TriggerKeysRec, *TriggerKeysList;
143 
144 static TriggerKeyRec trigger_keys_list[] = {
145   {XK_backslash, XK_Control_L, ControlMask}
146 }
147 #endif                          /* DYNAMIC_EVENT_FLOW_MODEL */
148 
149 
150 /*--------------------------------------------------------------------*
151  *                                                                    *
152  *                         Definition of Macro                        *
153  *                                                                    *
154  *--------------------------------------------------------------------*/
155 
156 /*
157  * assign a unique id.
158  */
159 #define ALLOC_ID(n)             (++n)
160 
161 /*
162  * shared CT string buffer.
163  */
164 #define GET_SHARED_CT_BUFFER()                  (ct_buf)
165 
166 /*
167  * swap data of protocol.
168  */
169 #define GET_CARD16(s)           \
170         ((CARD16)((need_byteswap() == True)? byteswap_s(s): s))
171 #define GET_CARD32(s)           \
172         ((CARD32)((need_byteswap() == True)? byteswap_l(s): s))
173 
174 /*
175  * Pad(n) for protocol data on 4-byte word boundory.
176  */
177 #define PAD(n)                  ((4 - (n) % 4) % 4)
178 
179 /*
180  * pre-make memory for frequent allocation of Request/Reply protocol data.
181  */
182 #define MALLOC_REQUEST(n)       \
183         (((n) > (sizeof buffer_request))? (CARD8 *)Malloc(n): &buffer_request[0])
184 #define MALLOC_REPLY(n)         \
185         (((n) > (sizeof buffer_reply))? (CARD8 *)Malloc(n): &buffer_reply[0])
186 #define FREE(p)                 \
187         {if ((p) != &buffer_request[0] && (p) != &buffer_reply[0]) XFree(p);}
188 
189 #define XIM_SERIALNUMBER(serial)  \
190                 (CARD16)(((unsigned long)serial >> 16) & 0xffff)
191 #define XIM_SET_SERIALNUMBER(serial)    \
192         (((unsigned long)serial & 0xffff) << 16)
193 
194 #define LENGTH_KEYSYM(f, k)     \
195         (((f)&XimLookupKeySym)? (sizeof(CARD16)+k): 0)
196 #define LENGTH_STRING_WITH_FLAG(f, n)   \
197         (((f)&XimLookupChars)? (sizeof(CARD16)+n+PAD(n)): 0)
198 
199 #define LENGTH_STRING(n)        ((n > 0) ?                                  \
200          (sizeof(CARD16) +                      /* 2 n string length */     \
201           n +                                   /* n string */              \
202           PAD(sizeof(CARD16) + n)): 0)  /* p Pad(2 + n) */
203 #define LENGTH_FEEDBACK(n)      ((n > 0)?                                   \
204          (sizeof(CARD16) +                      /* 2 m byte length */       \
205           sizeof(CARD16) +                      /* 2 unused */              \
206           sizeof(CARD32) * n): 0)       /* m LISTofXIMFEEDBACK */
207 
208 #define CUR_IM_ID()             (cur_x->im_id)
209 #define CUR_IC_ID()             (cur_x->number)
210 #define CUR_CLIENT_EVENT()      ((XEvent *)&(cur_x->cur_event))
211 
212 #define LENGTH_TEXT(t, sl, fn)  ((t == XIMTextType)?                        \
213         (LENGTH_STRING(sl) + LENGTH_FEEDBACK(fn)): 0)
214 #define LENGTH_PIXMAP(t)        ((t != XIMTextType)? sizeof(PIXMAP): 0)
215 
216 
217 /*--------------------------------------------------------------------*
218  *                                                                    *
219  *                         Definition of Local Variable               *
220  *                                                                    *
221  *--------------------------------------------------------------------*/
222 
223 static CARD8 buffer_request[BUFSIZ];    /* for protocol request */
224 static CARD8 buffer_reply[BUFSIZ];      /* for protocol reply */
225 
226 /*
227  * X selection atom, target and property in pre-connection.
228  */
229 static Atom transport_target;
230                                         /* atom name of TRANSPORT target */
231 static Atom locale_target;      /* atom name of LOCALE target */
232 static unsigned char *transport_prop;
233                                         /* string prop of TRANSPORT target */
234 static unsigned char *locale_prop;      /* string prop of LOCALE target */
235 
236 /*
237  * comma-separated list of locales supported by this server.
238  */
239 static unsigned char *locale_supported;
240 
241 static XIMContextList ximlist;  /* list of comming IM client */
242 static int cur_status;          /* current protol status */
243 static XIMID cur_im_id;         /* current client IM id */
244 static XICID cur_ic_id;         /* current client IC id */
245 static char cur_use_lang[BUFFER_MAX];
246                                         /* current lang from XIM_OPEN */
247 
248 /*
249  * list of IM attributes.
250  */
251 static XIMAttrRec im_attr[] = {
252   {ICInputStyle, XimType_XIMStyles, XNQueryInputStyle, NO_NEST},
253   END_OF_XIMATTRLIST
254 };
255 
256 /*
257  * list of IC preedit attributes.
258  */
259 static XIMAttrRec ic_attr_pre_area[] = {
260   {ICArea, XimType_XRectangle, XNArea, NO_NEST},
261   {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
262   {ICSpotLocation, XimType_XPoint, XNSpotLocation, NO_NEST},
263   {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
264   {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
265   {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
266   {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
267   {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
268   {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
269   {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
270   {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
271   {ICSeparatorOfNestedList,
272    XimType_SeparatorOfNestedList,
273    XNSeparatorofNestedList, NO_NEST},
274   END_OF_XIMATTRLIST
275 };
276 
277 /*
278  * list of IC status attributes.
279  */
280 static XIMAttrRec ic_attr_sts_area[] = {
281   {ICArea, XimType_XRectangle, XNArea, NO_NEST},
282   {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
283   {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
284   {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
285   {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
286   {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
287   {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
288   {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
289   {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
290   {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
291   {ICSeparatorOfNestedList,
292    XimType_SeparatorOfNestedList,
293    XNSeparatorofNestedList, NO_NEST},
294   END_OF_XIMATTRLIST
295 };
296 
297 /*
298  * list of IC attributes.
299  */
300 static XIMAttrRec ic_attr[] = {
301   {ICInputStyle, XimType_CARD32, XNInputStyle, NO_NEST},
302   {ICClientWindow, XimType_Window, XNClientWindow, NO_NEST},
303   {ICFocusWindow, XimType_Window, XNFocusWindow, NO_NEST},
304   {ICFilterEvents, XimType_CARD32, XNFilterEvents, NO_NEST},
305   {ICPreeditAttributes, XimType_NEST, XNPreeditAttributes, ic_attr_pre_area},
306   {ICStatusAttributes, XimType_NEST, XNStatusAttributes, ic_attr_sts_area},
307   END_OF_XIMATTRLIST
308 };
309 
310 /*
311  * list of extension supported.
312  */
313 static XIMQueryExtRec extension_list[] = {
314   {"XIM_EXT_SET_EVENT_MASK", XIM_EXT_SET_EVENT_MASK, 0},
315 #if defined(EXT_MOVE) || defined(SPOT)
316   {"XIM_EXT_MOVE", XIM_EXT_MOVE, 0}
317 #endif /* defined(EXT_MOVE) || defined(SPOT) */
318 };
319 
320 static CARD8 imattr_list[BUFSIZ];       /* packed im_attr list */
321 static CARD8 icattr_list[BUFSIZ];       /* packed ic_attr list */
322 static INT16 imattr_list_size;  /* byte length */
323 static INT16 icattr_list_size;  /* byte length */
324 
325 
326 /*--------------------------------------------------------------------*
327  *                                                                    *
328  *               Declaration of Extenal Variable and Function         *
329  *                                                                    *
330  *--------------------------------------------------------------------*/
331 
332 extern XIMCmblk *cur_cblk;      /* current client block */
333 
334 extern int XmuGetHostname ();   /* in SysUtil.h of Xmu */
335 
336 /*--------------------------------------------------------------------*
337  *                                                                    *
338  *               Definition of Public Variable and Function           *
339  *                                                                    *
340  *--------------------------------------------------------------------*/
341 
342 Atom server_id;                 /* atom name of this server "@im" */
343 
344 int xim_send_nofilter ();       /* used before its definition. */
345 
346 /*--------------------------------------------------------------------*
347  *                                                                    *
348  *                         Private Functions                          *
349  *                                                                    *
350  *--------------------------------------------------------------------*/
351 
352 /*
353  *    Function Name : _WriteToClientFlush()
354  *    Description   : write data to client immediately with flush action.
355  *                    same as do_socket.c: _WriteToClient() if no flush.
356  *    Parameter     :
357  *      p           : pointer to data.
358  *      num         : byte length of data.
359  *    Returned Value:
360  *        >= 0      : byte length of data written to client.
361  *        < 0       : error in writing.
362  */
363 static int
_WriteToClientFlush(p,num)364 _WriteToClientFlush (p, num)
365      char *p;
366      int num;
367 {
368   int ret;
369 
370   if ((ret = _WriteToClient (p, num)) >= 0)
371     {
372       if (_Send_Flush () == 0)
373         return ret;             /* success */
374     }
375   return ret;
376 }
377 
378 /*
379  *    Function Name : _XimWireToEvent()
380  *    Description   : convert xEvent to XEvent, modified from Xlibint.c:
381  *                    _XWireToEvent().
382  *    Parameter     :
383  *      dpy         : pointer to X display.
384  *      serial      : serial number of event.
385  *      event       : pointer to data of X protocol xEvent
386  *      re          : pointer to data of XEvent, returned.
387  *    Returned Value:
388  *      True        : conversion is successful.
389  *      False       : error.
390  */
391 static Bool
_XimWireToEvent(dpy,serial,event,re)392 _XimWireToEvent (dpy, serial, event, re)
393      register Display *dpy;     /* pointer to display structure */
394      register int serial;       /* serial number of event */
395      register xEvent *event;    /* wire protocol event */
396      register XEvent *re;       /* pointer to where event should be reformatted */
397 {
398 
399   re->type = event->u.u.type & 0x7f;
400   ((XAnyEvent *) re)->serial = XIM_SET_SERIALNUMBER (serial);
401   ((XAnyEvent *) re)->send_event = ((event->u.u.type & 0x80) != 0);
402   ((XAnyEvent *) re)->display = dpy;
403 
404   /* Ignore the leading bit of the event type since it is set when a
405      client sends an event rather than the server. */
406 
407   switch (event->u.u.type & 0177)
408     {
409     case KeyPress:
410     case KeyRelease:
411       {
412         register XKeyEvent *ev = (XKeyEvent *) re;
413         ev->root = event->u.keyButtonPointer.root;
414         ev->window = event->u.keyButtonPointer.event;
415         ev->subwindow = event->u.keyButtonPointer.child;
416         ev->time = event->u.keyButtonPointer.time;
417         ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
418         ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
419         ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
420         ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
421         ev->state = event->u.keyButtonPointer.state;
422         ev->same_screen = event->u.keyButtonPointer.sameScreen;
423         ev->keycode = event->u.u.detail;
424       }
425       break;
426     case ButtonPress:
427     case ButtonRelease:
428       {
429         register XButtonEvent *ev = (XButtonEvent *) re;
430         ev->root = event->u.keyButtonPointer.root;
431         ev->window = event->u.keyButtonPointer.event;
432         ev->subwindow = event->u.keyButtonPointer.child;
433         ev->time = event->u.keyButtonPointer.time;
434         ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
435         ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
436         ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
437         ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
438         ev->state = event->u.keyButtonPointer.state;
439         ev->same_screen = event->u.keyButtonPointer.sameScreen;
440         ev->button = event->u.u.detail;
441       }
442       break;
443     default:
444       return False;
445     }
446   return True;
447 }
448 
449 /*
450  *    Function Name : _XimEventToWire()
451  *    Description   : convert XEvent to xEvent, modified from EvToWire.c:
452  *                    _XEventToWire().
453  *    Parameter     :
454  *      re          : pointer to data of XEvent.
455  *      event       : pointer to data of X protocol xEvent, returned
456  *    Returned Value:
457  *      True        : conversion is successful.
458  *      False       : error.
459  */
460 static Bool
_XimEventToWire(re,event)461 _XimEventToWire (re, event)
462      register XEvent *re;       /* pointer to where event should be reformatted */
463      register xEvent *event;    /* wire protocol event */
464 {
465   switch (event->u.u.type = re->type)
466     {
467     case KeyPress:
468     case KeyRelease:
469       {
470         register XKeyEvent *ev = (XKeyEvent *) re;
471         event->u.keyButtonPointer.root = ev->root;
472         event->u.keyButtonPointer.event = ev->window;
473         event->u.keyButtonPointer.child = ev->subwindow;
474         event->u.keyButtonPointer.time = ev->time;
475         event->u.keyButtonPointer.eventX = ev->x;
476         event->u.keyButtonPointer.eventY = ev->y;
477         event->u.keyButtonPointer.rootX = ev->x_root;
478         event->u.keyButtonPointer.rootY = ev->y_root;
479         event->u.keyButtonPointer.state = ev->state;
480         event->u.keyButtonPointer.sameScreen = ev->same_screen;
481         event->u.u.detail = ev->keycode;
482       }
483       break;
484     case ButtonPress:
485     case ButtonRelease:
486       {
487         register XButtonEvent *ev = (XButtonEvent *) re;
488         event->u.keyButtonPointer.root = ev->root;
489         event->u.keyButtonPointer.event = ev->window;
490         event->u.keyButtonPointer.child = ev->subwindow;
491         event->u.keyButtonPointer.time = ev->time;
492         event->u.keyButtonPointer.eventX = ev->x;
493         event->u.keyButtonPointer.eventY = ev->y;
494         event->u.keyButtonPointer.rootX = ev->x_root;
495         event->u.keyButtonPointer.rootY = ev->y_root;
496         event->u.keyButtonPointer.state = ev->state;
497         event->u.keyButtonPointer.sameScreen = ev->same_screen;
498         event->u.u.detail = ev->button;
499       }
500       break;
501     default:
502       return False;
503     }
504   return True;
505 }
506 
507 /*
508  * get list of locale names as the format:
509  *            "locale_1,locale_2,...,locale_n"
510  * and return the length of the string above.
511  */
512 static char *
GetLocaleSupported()513 GetLocaleSupported ()
514 {
515   return (!xim->supported_language) ? "C" : xim->supported_language;
516 }
517 
518 /*
519  *    Function Name : _CheckLocaleName()
520  *    Description   : check if the client locale is supported in this server.
521  *    Parameter     :
522  *      buf         : string buffer of client locale.
523  *      loc_name    : comma-separated list of locales supported in this server.
524  *    Returned Value:
525  *      True        : it is supported.
526  *      False       : not supproted.
527  */
528 static Bool
_CheckLocaleName(buf,loc_name)529 _CheckLocaleName (buf, loc_name)
530      CARD8 *buf;
531      char *loc_name;
532 {
533   int str_len = (int) buf[0];
534   int len;
535   char *ptr = (char *) locale_supported;
536   char *str = (char *) &buf[1];
537   register char *p;
538 
539   loc_name[0] = '\0';
540   for (;;)
541     {
542       for (p = ptr; ((*p != ',') && (*p)); p++);
543       len = (int) (p - ptr);
544       if ((str_len == len) && (!strncmp (str, ptr, len)))
545         {
546           (void) strncpy (loc_name, str, len);
547           loc_name[len] = '\0';
548           return True;
549         }
550       if (!(*p))
551         break;
552       ptr = p + 1;
553     }
554   return False;
555 }
556 
557 /*
558  *    Function Name : GetIMWithId()
559  *    Description   : search a client context with IM id.
560  *    Parameter     :
561  *      im_id       : client input-method-id.
562  *    Returned Value:
563  *      XIMContextRec *
564  *                  : pointer to the client context found.
565  *      NULL        : not found.
566  */
567 static XIMContextRec *
GetIMWithId(im_id)568 GetIMWithId (im_id)
569      register XIMID im_id;
570 {
571   register XIMContextRec *im;
572 
573   for (im = ximlist; im; im = im->next)
574     {
575       if (im->im_id == im_id)
576         return im;
577     }
578   return (XIMContextRec *) NULL;
579 }
580 
581 /*
582  *    Function Name : RemoveIMWithId()
583  *    Description   : remove a IM client context.
584  *    Parameter     :
585  *      im_id       : client input-method-id.
586  *    Returned Value:
587  *      True        : the IM client context with im_id is removed from list
588  *                    and is freed its memory.
589  *      False       : not found with this im_id.
590  */
591 static Bool
RemoveIMWithId(im_id)592 RemoveIMWithId (im_id)
593      XIMID im_id;
594 {
595   register XIMContextRec *im, *pre_im;
596 
597   for (im = pre_im = ximlist; im; pre_im = im, im = im->next)
598     {
599       if (im->im_id == im_id)
600         {
601           if (pre_im != im)
602             {
603               pre_im->next = im->next;
604             }
605           else
606             {
607               ximlist = im->next;
608             }
609           break;
610         }
611     }
612   if (!im)
613     return False;
614   XFree ((char *) im);
615   return True;
616 }
617 
618 /*
619  *    Function Name : GetICWithId()
620  *    Description   : search a client structure with IC id.
621  *    Parameter     :
622  *      ic_id       : client input-context-id.
623  *    Returned Value:
624  *      XIMClientRec*
625  *                  : pointer to the client structure found.
626  *      NULL        : not found.
627  */
628 static XIMClientRec *
GetICWithId(ic_id)629 GetICWithId (ic_id)
630      register int ic_id;
631 {
632   register XIMClientRec *xc;
633 
634   for (xc = ximclient_list; xc != NULL; xc = xc->next)
635     {
636       if (xc->number == ic_id)
637         return xc;
638     }
639   return (XIMClientRec *) NULL;
640 }
641 
642 /*
643  *    Function Name : AddHead()
644  *    Description   : fill head data to a protocol reply which will be
645  *                    sent to client.  The head data to be filed is as follows:
646  *                        CARD8  major_opcode
647  *                        CARD8  minor_opcode
648  *                        CARD16 data length in 4-byte word
649  *    Parameter     :
650  *      reply       : pointer to a protocol reply structure, which is
651  *                    to be filled head data.
652  *      major_code  : major opcode of this protocol.
653  *      minor_code  : minor opcode of this protocol.
654  *      len         : data length of protocol except head.
655  *    Returned Value:
656  *      > 0         : byte length of head data, always XIM_HEADER_SIZE.
657  */
658 static int
AddHead(reply,major_code,minor_code,len)659 AddHead (reply, major_code, minor_code, len)
660      CARD8 *reply;
661      CARD8 major_code;
662      CARD8 minor_code;
663      int len;
664 {
665   CARD8 *buf_8 = reply;
666   CARD16 *buf_16 = (CARD16 *) (reply + sizeof (CARD8) * 2);
667 
668   buf_8[0] = major_code;
669   buf_8[1] = minor_code;
670   buf_16[0] = GET_CARD16 (len / 4);
671   return XIM_HEADER_SIZE;
672 }
673 
674 /*
675  *    Function Name : SetClientSync()
676  *    Description   : set the client to a sync flag.
677  *    Parameter     :
678  *      xc          : pointer to a client structure.
679  *      sync        : flag of sync.
680  *    Returned Value:
681  *      <none>
682  */
683 #ifdef NEED_FUNCTION
684 
685 static void
SetClientSync(xc,sync)686 SetClientSync (xc, sync)
687      XIMClientRec *xc;
688      Bool sync;
689 {
690   xc->sync_needed = sync;
691 }
692 
693 static Bool
AllSyncDone(im_id,ic_id)694 AllSyncDone (im_id, ic_id)
695      XIMID im_id;
696      XICID im_cd;
697 {
698   return True;
699 }
700 
701 static void
SyncAll(im_id,ic_id)702 SyncAll (im_id, ic_id)
703      XIMID im_id;
704      XICID im_cd;
705 {
706 }
707 
708 #else
709 
710 #define SetClientSync(xc, sync)                 ((xc)->sync_needed = sync)
711 #define AllSyncDone(im_id, ic_id)               (True)
712 #define SyncAll(im_id, ic_id)
713 
714 #endif /* NEED_FUNCTION */
715 
716 /*
717  *    Function Name : ClientSyncDone()
718  *    Description   : If this client has True flag needed to do sync, do it
719  *                    and turn off the sync flag (False).
720  *    Parameter     :
721  *      xc          : pointer to a client structure.
722  *    Returned Value:
723  *      True        : yes, sync has done.
724  *      False       : no sync.
725  */
726 static Bool
ClientSyncDone(xc)727 ClientSyncDone (xc)
728      XIMClientRec *xc;
729 {
730   Bool sync_done;
731 
732   sync_done = xc->sync_needed;
733   xc->sync_needed = False;
734   return sync_done;
735 }
736 
737 /*
738  *    Function Name : GetAuth()
739  *    Description   : get names of authentification from IM library.
740  *    Parameter     :
741  *      list        : buffer list.
742  *      num         : number of list elements.
743  *      length      : byte length of buffer list.
744  *      names_returned
745  *                  : auth name returned.
746  *    Returned Value:
747  *      True        : successed.
748  *      False       : wrong auth name.
749  */
750 
751  /*ARGSUSED*/ static Bool
GetAuth(list,num,length,names_return)752 GetAuth (list, num, length, names_return)
753      CARD8 *list;
754      int num;
755      int length;
756      char *names_return;
757 {
758   /* it is free authentification so far. */
759   return True;
760 }
761 
762 /*
763  *    Function Name : CreateAttrList()
764  *    Description   : pack IM/IC attribute list to a compact data.
765  *    Parameter     :
766  *      table       : list of IM/IC attributes, end with the empty name.
767  *      list        : returned data that contains packed list of attribute.
768  *    Returned Value:
769  *      >= 0        : byte length of packed list.
770  */
771 static int
CreateAttrList(table,list)772 CreateAttrList (table, list)
773      XIMAttrList table;
774      CARD8 *list;
775 {
776   CARD16 *buf_16;
777   INT16 total = 0;
778   int len, i;
779 
780   for (i = 0; table[i].name; i++)
781     {
782       buf_16 = (CARD16 *) list;
783       len = strlen (table[i].name);
784       buf_16[0] = GET_CARD16 (table[i].attr_id);        /* 2 attr ID */
785       buf_16[1] = GET_CARD16 (table[i].type);   /* 2 type */
786       buf_16[2] = GET_CARD16 (len);     /* 2 length */
787       memcpy ((char *) &buf_16[3], table[i].name, len); /* n attr */
788       len = sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16) + len + PAD (len + 2);
789       list += len;
790       total += len;
791       if (table[i].nest)
792         {
793           len = CreateAttrList (table[i].nest, list);
794           list += len;
795           total += len;
796         }
797     }
798   return total;
799 }
800 
801 /*
802  *    Function Name : InitiateProtocol()
803  *    Description   : do some initial works.
804  *    Parameter     :
805  *      <none>
806  *    Returned Value:
807  *      <none>
808  */
809 static void
InitiateProtocol()810 InitiateProtocol ()
811 {
812   ximlist = (XIMContextList) NULL;
813 
814   imattr_list_size = CreateAttrList (im_attr, imattr_list);
815   icattr_list_size = CreateAttrList (ic_attr, icattr_list);
816 }
817 
818 /*
819  *    Function Name : CheckInputStyle()
820  *    Description   : check if the passed input style is supported.
821  *    Parameter     :
822  *      input_style : the input style to be checked.
823  *    Returned Value:
824  *      True        : supported.
825  *      False       : not supported.
826  */
827 static Bool
CheckInputStyle(input_style)828 CheckInputStyle (input_style)
829      INT32 input_style;
830 {
831   int i;
832 
833   for (i = 0; i < MAX_SUPPORT_STYLE; i++)
834     {
835       if (xim->supported_style[i] == input_style)
836         {
837           return True;
838         }
839     }
840   return False;
841 }
842 
843 /*
844  *    Function Name : ConvErrorCode()
845  *    Description   : convert error code used in Xsi R5 IM to R6 IM.
846  *    Parameter     :
847  *      x11r5_code  : error code of Xsi R5 IM.
848  *    Returned Value:
849  *      > 0         : errro code of R6 IM
850  */
851 static int
ConvErrorCode(x11r5_code)852 ConvErrorCode (x11r5_code)
853      short x11r5_code;
854 {
855   switch (x11r5_code)
856     {
857     case AllocError:
858       return XIM_BadAlloc;
859     case BadStyle:
860       return XIM_BadStyle;
861     case BadClientWindow:
862       return XIM_BadClientWindow;
863     case BadFocusWindow:
864       return XIM_BadFocusWindow;
865     case BadLanguage:
866       return XIM_LocaleNotSupported;
867     case BadSpotLocation:
868       return XIM_BadSpotLocation;
869     case BadFontSet:
870       return XIM_BadName;       /* or XIM_BadStyle */
871     default:
872       return XIM_BadSomething;
873     }
874 }
875 
876 /*
877  *    Function Name : ConvAreaAttr()
878  *    Description   : convert byte data to IC attribute of Area.
879  *    Parameter     :
880  *      value       : the byte data.
881  *      size        : byte length of the data.
882  *      ic_attr_req : contain Area attribute to be filled.
883  *    Returned Value:
884  *      = 0         : successed.
885  *      > 0         : error, the number is error code.
886  */
887 static int
ConvAreaAttr(value,size,ic_attr_req)888 ConvAreaAttr (value, size, ic_attr_req)
889      CARD8 *value;
890      int size;
891      ximICAttributesReq *ic_attr_req;
892 {
893   CARD16 *buf_16 = (CARD16 *) value;
894 
895   if (size != (sizeof (CARD16) << 2))
896     return XIM_BadAlloc;
897 
898   ic_attr_req->area_x = (INT16) GET_CARD16 (buf_16[0]);
899   ic_attr_req->area_y = (INT16) GET_CARD16 (buf_16[1]);
900   ic_attr_req->area_width = GET_CARD16 (buf_16[2]);
901   ic_attr_req->area_height = GET_CARD16 (buf_16[3]);
902   return 0;
903 }
904 
905 /*
906  *    Function Name : ConvAreaNeededAttr()
907  *    Description   : convert byte data to IC attribute of AreaNeeded.
908  *    Parameter     :
909  *      value       : the byte data.
910  *      size        : byte length of the data.
911  *      ic_attr_req : contain AreaNeeded attribute to be filled.
912  *    Returned Value:
913  *      = 0         : successed.
914  *      > 0         : error, the number is error code.
915  */
916 static int
ConvAreaNeededAttr(value,size,ic_attr_req)917 ConvAreaNeededAttr (value, size, ic_attr_req)
918      CARD8 *value;
919      int size;
920      ximICAttributesReq *ic_attr_req;
921 {
922   CARD16 *buf_16 = (CARD16 *) value;
923 
924   if (size != (sizeof (CARD16) << 2))
925     return XIM_BadAlloc;
926 
927   ic_attr_req->areaneeded_width = GET_CARD16 (buf_16[2]);
928   ic_attr_req->areaneeded_height = GET_CARD16 (buf_16[3]);
929   return 0;
930 }
931 
932 /*
933  *    Function Name : ConvSpotAttr()
934  *    Description   : convert byte data to IC attribute of Spot.
935  *    Parameter     :
936  *      value       : the byte data.
937  *      size        : byte length of the data.
938  *      ic_attr_req : contain Spot attribute to be filled.
939  *    Returned Value:
940  *      = 0         : successed.
941  *      > 0         : error, the number is error code.
942  */
943 static int
ConvSpotAttr(value,size,ic_attr_req)944 ConvSpotAttr (value, size, ic_attr_req)
945      CARD8 *value;
946      int size;
947      ximICAttributesReq *ic_attr_req;
948 {
949   CARD16 *buf_16 = (CARD16 *) value;
950 
951   if (size != (sizeof (CARD16) + sizeof (CARD16)))
952     return XIM_BadAlloc;
953 
954   ic_attr_req->spot_x = (INT16) GET_CARD16 (buf_16[0]);
955   ic_attr_req->spot_y = (INT16) GET_CARD16 (buf_16[1]);
956   return 0;
957 }
958 
959 /*
960  *    Function Name : ConvFontSetAttr()
961  *    Description   : convert byte data to IC attribute of FontSet name.
962  *    Parameter     :
963  *      value       : the byte data.
964  *      size        : byte length of the data.
965  *      ic_attr_req : contain FontSet attribute to be filled.
966  *    Returned Value:
967  *      = 0         : successed.
968  *      > 0         : error, the number is error code.
969  */
970 static int
ConvFontSetAttr(value,size,base_font_name)971 ConvFontSetAttr (value, size, base_font_name)
972      CARD8 *value;
973      int size;
974      char **base_font_name;
975 {
976   CARD16 *buf_16 = (CARD16 *) value;
977   char *fname;
978   int len;
979 
980   len = (int) GET_CARD16 (buf_16[0]);
981   if (len > size)
982     return XIM_BadAlloc;
983   if (!(fname = Malloc (len + 1)))
984     return XIM_BadAlloc;
985   (void) strncpy (fname, (char *) &buf_16[1], len);
986   fname[len] = '\0';
987   *base_font_name = fname;
988   return 0;
989 }
990 
991 /*
992  *    Function Name : DecodeICNestedAttributes()
993  *    Description   : decode IC nested attributes
994  *    Parameter     :
995  *      list        : list of IC attribute, packed data.
996  *      size        : byte length of list.
997  *      ic_attr_req : IC attribute structure to be filled.
998  *      font        : base font name to be returned.  The caller should
999  *                    free it after use.
1000  *    Returned Value:
1001  *      = 0         : successed.
1002  *      > 0         : error, the number is error code.
1003  */
1004 static int
DecodeICNestedAttributes(list,size,mask,ic_attr_req,font)1005 DecodeICNestedAttributes (list, size, mask, ic_attr_req, font)
1006      CARD8 *list;
1007      int size;
1008      CARD32 *mask;
1009      ximICAttributesReq *ic_attr_req;
1010      char **font;
1011 {
1012   CARD16 *buf_16;
1013   CARD32 *buf_32;
1014   CARD32 mask_base, mask_ret;
1015   int ret, have_more;
1016   int len, tmpl, attr_id;
1017 
1018   ret = 0;
1019   mask_base = *mask;
1020   mask_ret = 0;
1021   have_more = 1;
1022   while (size > 0 && have_more)
1023     {
1024       buf_16 = (CARD16 *) list;
1025       attr_id = (int) GET_CARD16 (buf_16[0]);   /* 2 attribute id */
1026       len = (int) GET_CARD16 (buf_16[1]);       /* n length of value */
1027       tmpl = sizeof (CARD16) + sizeof (CARD16);
1028       list += tmpl;
1029       size -= tmpl;
1030       buf_16 = (CARD16 *) list;
1031       buf_32 = (CARD32 *) list;
1032       switch (attr_id)
1033         {
1034         case ICArea:
1035           mask_ret |= (1 << (ICArea + mask_base));
1036           ret = ConvAreaAttr (list, len, ic_attr_req);
1037           break;
1038         case ICAreaNeeded:
1039           mask_ret |= (1 << (ICAreaNeeded + mask_base));
1040           ret = ConvAreaNeededAttr (list, len, ic_attr_req);
1041           break;
1042         case ICSpotLocation:
1043           mask_ret |= (1 << (ICSpotLocation + mask_base));
1044           ret = ConvSpotAttr (list, len, ic_attr_req);
1045           break;
1046         case ICColormap:
1047           mask_ret |= (1 << (ICColormap + mask_base));
1048           ic_attr_req->colormap = (Colormap) GET_CARD32 (buf_32[0]);
1049           break;
1050         case ICStdColormap:
1051           mask_ret |= (1 << (ICStdColormap + mask_base));
1052           ic_attr_req->std_colormap = (Atom) GET_CARD32 (buf_32[0]);
1053           break;
1054         case ICForeground:
1055           mask_ret |= (1 << (ICForeground + mask_base));
1056           ic_attr_req->foreground = GET_CARD32 (buf_32[0]);
1057           break;
1058         case ICBackground:
1059           mask_ret |= (1 << (ICBackground + mask_base));
1060           ic_attr_req->background = GET_CARD32 (buf_32[0]);
1061           break;
1062         case ICBackgroundPixmap:
1063           mask_ret |= (1 << (ICBackgroundPixmap + mask_base));
1064           ic_attr_req->pixmap = (Pixmap) GET_CARD32 (buf_32[0]);
1065           break;
1066         case ICFontSet:
1067           mask_ret |= (1 << (ICFontSet + mask_base));
1068           ret = ConvFontSetAttr (list, len, font);
1069           break;
1070         case ICLineSpace:
1071           mask_ret |= (1 << (ICLineSpace + mask_base));
1072           ic_attr_req->line_space = (INT16) GET_CARD32 (buf_32[0]);
1073           break;
1074         case ICCursor:
1075           mask_ret |= (1 << (ICCursor + mask_base));
1076           ic_attr_req->cursor = (Cursor) GET_CARD32 (buf_32[0]);
1077           break;
1078         case ICSeparatorOfNestedList:
1079           have_more = 0;
1080           break;
1081         default:
1082           have_more = 0;
1083           continue;
1084         }
1085       if (ret)
1086         return ret;
1087       len = len +               /* n value */
1088         PAD (len);              /* p Pad(n) */
1089       list += len;
1090       size -= len;
1091     }
1092   *mask = mask_ret;
1093   return 0;
1094 }
1095 
1096 /*
1097  *    Function Name : DecodeICAttributes()
1098  *    Description   : parse all IC attributes
1099  *    Parameter     :
1100  *      list        : list of IC attributes, packed data.
1101  *      size        : byte length of list.
1102  *      ic_attr_req : IC attribute structure to be filled.
1103  *      pre_req     : preedit attributes to be filled.
1104  *      st_req      : status attributes to be filled.
1105  *      pre_font    : preedit base font name to be returned.  The caller should
1106  *                    free it after use.
1107  *      st_font     : status base font name to be returned.  The caller should
1108  *                    free it after use.
1109  *    Returned Value:
1110  *      = 0         : successed.
1111  *      > 0         : error, the number is error code.
1112  */
1113 static int
DecodeICAttributes(list,size,ic_req,pre_req,st_req,pre_font,st_font)1114 DecodeICAttributes (list, size, ic_req, pre_req, st_req, pre_font, st_font)
1115      CARD8 *list;
1116      int size;
1117      ximICValuesReq *ic_req;
1118      ximICAttributesReq *pre_req;
1119      ximICAttributesReq *st_req;
1120      char **pre_font;
1121      char **st_font;
1122 {
1123   CARD16 *buf_16;
1124   CARD32 *buf_32;
1125   CARD32 mask;
1126   int ret, len, attr_id;
1127   int tmpl;
1128 
1129   ret = 0;
1130   ic_req->mask = (CARD32) 0;
1131   while (size > 0)
1132     {
1133       buf_16 = (CARD16 *) list;
1134       attr_id = (int) GET_CARD16 (buf_16[0]);
1135       len = (int) GET_CARD16 (buf_16[1]);
1136       tmpl = sizeof (CARD16) +  /* 2 attribute id */
1137         sizeof (CARD16);        /* 2 value length */
1138       list += tmpl;
1139       size -= tmpl;
1140       buf_16 = (CARD16 *) list;
1141       buf_32 = (CARD32 *) list;
1142       switch (attr_id)
1143         {
1144         case ICInputStyle:
1145           ic_req->mask |= (1 << ICInputStyle);
1146           ic_req->input_style = (INT32) GET_CARD32 (buf_32[0]);
1147           break;
1148         case ICClientWindow:
1149           ic_req->mask |= (1 << ICClientWindow);
1150           ic_req->c_window = (Window) GET_CARD32 (buf_32[0]);
1151           break;
1152         case ICFocusWindow:
1153           ic_req->mask |= (1 << ICFocusWindow);
1154           ic_req->focus_window = (Window) GET_CARD32 (buf_32[0]);
1155           break;
1156         case ICFilterEvents:
1157           ic_req->mask |= (1 << ICFilterEvents);
1158           ic_req->filter_events = GET_CARD32 (buf_32[0]);
1159           break;
1160         case ICPreeditAttributes:
1161           mask = 0;
1162           ret = DecodeICNestedAttributes (list, len, &mask, pre_req, pre_font);
1163           ic_req->mask |= mask;
1164           break;
1165         case ICStatusAttributes:
1166           mask = StatusOffset;
1167           ret = DecodeICNestedAttributes (list, len, &mask, st_req, st_font);
1168           ic_req->mask |= mask;
1169           break;
1170         default:
1171           ret = XIM_BadProtocol;
1172           break;
1173         }
1174       if (ret)
1175         return ret;
1176       len = len +               /* n value */
1177         PAD (len);              /* p Pad(n) */
1178       list += len;
1179       size -= len;
1180     }
1181   return 0;
1182 }
1183 
1184 /*
1185  *    Function Name : SetClientICValues()
1186  *    Description   : set IC values to a client structure.
1187  *    Parameter     :
1188  *      list        : list of IC attributes, packed data.
1189  *      size        : byte length of list.
1190  *      xc          : pointer to client structure.
1191  *    Returned Value:
1192  *      = 0         : successed.
1193  *      > 0         : error, the number is error code.
1194  */
1195 static int
SetClientICValues(list,size,xc)1196 SetClientICValues (list, size, xc)
1197      CARD8 *list;
1198      int size;
1199      XIMClientRec *xc;
1200 {
1201   ximICValuesReq ic_req;
1202   ximICAttributesReq pre_req, st_req;
1203   XIMNestLangRec *p = (XIMNestLangRec *) NULL;
1204   char *pre_font = (char *) NULL;
1205   char *st_font = (char *) NULL;
1206   int cur_is_world = 0;
1207   int ret;
1208   short detail;
1209   extern int change_client ();
1210 
1211   /* parse IC attributes */
1212   ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
1213   if (ret)
1214     return ret;
1215 
1216   /* refer to util: ChangeIC() */
1217 
1218   ret = change_client (xc, &ic_req, &pre_req, &st_req, p, cur_is_world, pre_font, st_font, &detail);
1219   if (pre_font)
1220     XFree (pre_font);
1221   if (st_font)
1222     XFree (st_font);
1223   if (p)
1224     free_langlist (p);
1225   if (ret == -1)
1226     return ConvErrorCode (detail);
1227   return 0;
1228 }
1229 
1230 /*
1231  *    Function Name : EncodeRectangleAttr()
1232  *    Description   : encode XRectangle to byte data.
1233  *    Parameter     :
1234  *      rect        : pointer to the rectangle structure.
1235  *      value       : encoded byte data.
1236  *      size_return : returned byte length of the data.
1237  *    Returned Value:
1238  *      = 0         : successed.
1239  *      > 0         : error, the number is error code.
1240  */
1241 static int
EncodeRectangleAttr(rect,value,size_return)1242 EncodeRectangleAttr (rect, value, size_return)
1243      XRectangle *rect;
1244      CARD8 *value;
1245      int *size_return;
1246 {
1247   CARD16 *buf_16 = (CARD16 *) value;
1248 
1249   buf_16[0] = GET_CARD16 (rect->x);
1250   buf_16[1] = GET_CARD16 (rect->y);
1251   buf_16[2] = GET_CARD16 (rect->width);
1252   buf_16[3] = GET_CARD16 (rect->height);
1253   *size_return = sizeof (CARD16) +      /* 2 X */
1254     sizeof (CARD16) +           /* 2 Y */
1255     sizeof (CARD16) +           /* 2 width */
1256     sizeof (CARD16);            /* 2 height */
1257   return 0;
1258 }
1259 
1260 /*
1261  *    Function Name : EncodePointAttr()
1262  *    Description   : encode XPoint to byte data.
1263  *    Parameter     :
1264  *      rect        : pointer to the XPoint structure.
1265  *      value       : encoded byte data.
1266  *      size_return : returned byte length of the data.
1267  *    Returned Value:
1268  *      = 0         : successed.
1269  *      > 0         : error, the number is error code.
1270  */
1271 static int
EncodePointAttr(xc,value,size_return)1272 EncodePointAttr (xc, value, size_return)
1273      XIMClientRec *xc;
1274      CARD8 *value;
1275      int *size_return;
1276 {
1277   CARD16 *buf_16 = (CARD16 *) value;
1278   short spot_x, spot_y;
1279 
1280   spot_x = xc->point.x;
1281   spot_y = xc->point.y + FontAscent (xc->cur_xl);
1282   buf_16[0] = GET_CARD16 (spot_x);
1283   buf_16[1] = GET_CARD16 (spot_y);
1284   *size_return = sizeof (CARD16) +      /* 2 X */
1285     sizeof (CARD16);            /* 2 Y */
1286   return 0;
1287 }
1288 
1289 /*
1290  *    Function Name : EncodeFontSetAttr()
1291  *    Description   : encode name of base font set to byte data.
1292  *    Parameter     :
1293  *      rect        : pointer to the name.
1294  *      value       : encoded byte data.
1295  *      size_return : returned byte length of the data.
1296  *    Returned Value:
1297  *      = 0         : successed.
1298  *      > 0         : error, the number is error code.
1299  */
1300 static int
EncodeFontSetAttr(base_font_name,value,size_return)1301 EncodeFontSetAttr (base_font_name, value, size_return)
1302      char *base_font_name;
1303      CARD8 *value;
1304      int *size_return;
1305 {
1306   CARD16 *buf_16 = (CARD16 *) value;
1307   int len;
1308 
1309   len = strlen ((char *) base_font_name);
1310   buf_16[0] = GET_CARD16 (len);
1311   (void) strncpy ((char *) &buf_16[1], (char *) base_font_name, len);
1312   *size_return = sizeof (CARD16) + len + PAD (sizeof (CARD16) + len);
1313   return 0;
1314 }
1315 
1316 /*
1317  *    Function Name : EncodeICNestedAttributes()
1318  *    Description   : encode IC nested attribute structure to byte data.
1319  *    Parameter     :
1320  *      attr_id_list: list of IC attribute id.
1321  *      size        : byte lenth of the list.
1322  *      xc          : pointer to client structure.
1323  *      ic_attr     : pointer to IC nested attribute structure.
1324  *      value       : encoded byte data.
1325  *      size_return : returned byte length of the data.
1326  *      num_return  : returned number of IC attributes.
1327  *    Returned Value:
1328  *      = 0         : successed.
1329  *      > 0         : error, the number is error code.
1330  */
1331 static int
EncodeICNestedAttributes(attr_id_list,size,xc,ic_attr,value,size_return,num_return)1332 EncodeICNestedAttributes (attr_id_list, size, xc, ic_attr, value, size_return, num_return)
1333      CARD8 *attr_id_list;
1334      int size;
1335      XIMClientRec *xc;
1336      XIMAttributes *ic_attr;
1337      CARD8 *value;
1338      int *size_return;
1339      int *num_return;
1340 {
1341   CARD8 *data;
1342   CARD16 *buf_16;
1343   CARD32 *buf_32;
1344   int ret, len, total, num, attr_id;
1345   int have_more;
1346 
1347   ret = 0;
1348   total = num = 0;
1349   have_more = 1;
1350   while (size > 0 && have_more)
1351     {
1352       buf_16 = (CARD16 *) attr_id_list;
1353       attr_id = (int) GET_CARD16 (buf_16[0]);
1354       data = value + sizeof (CARD16) + sizeof (CARD16);
1355       buf_16 = (CARD16 *) data;
1356       buf_32 = (CARD32 *) data;
1357       switch (attr_id)
1358         {
1359         case ICArea:
1360           ret = EncodeRectangleAttr (&(ic_attr->area), data, &len);
1361           break;
1362         case ICAreaNeeded:
1363           ret = EncodeRectangleAttr (&(ic_attr->area_needed), data, &len);
1364           break;
1365         case ICSpotLocation:
1366           ret = EncodePointAttr (xc, data, &len);
1367           break;
1368         case ICColormap:
1369           len = sizeof (CARD32);
1370           buf_32[0] = GET_CARD32 (ic_attr->colormap);
1371           break;
1372         case ICStdColormap:
1373           len = sizeof (CARD32);
1374           buf_32[0] = GET_CARD32 (ic_attr->std_colormap);
1375           break;
1376         case ICForeground:
1377           len = sizeof (CARD32);
1378           buf_32[0] = GET_CARD32 (ic_attr->fg);
1379           break;
1380         case ICBackground:
1381           len = sizeof (CARD32);
1382           buf_32[0] = GET_CARD32 (ic_attr->bg);
1383           break;
1384         case ICBackgroundPixmap:
1385           len = sizeof (CARD32);
1386           buf_32[0] = GET_CARD32 (ic_attr->bg_pixmap);
1387           break;
1388         case ICFontSet:
1389           ret = EncodeFontSetAttr (ic_attr->fontset, data, &len);
1390           break;
1391         case ICLineSpace:
1392           len = sizeof (CARD32);
1393           buf_32[0] = GET_CARD32 (ic_attr->line_space);
1394           break;
1395         case ICCursor:
1396           len = sizeof (CARD32);
1397           buf_32[0] = GET_CARD32 (ic_attr->cursor);
1398           break;
1399         case ICSeparatorOfNestedList:
1400           len = 0;
1401           have_more = 0;
1402           break;
1403         default:
1404           have_more = 0;
1405           continue;
1406         }
1407       if (ret)
1408         return ret;
1409       buf_16 = (CARD16 *) value;
1410       buf_16[0] = GET_CARD16 (attr_id);
1411       buf_16[1] = GET_CARD16 (len);
1412       len = sizeof (CARD16) +   /* 2 attribute-id */
1413         sizeof (CARD16) +       /* 2 byte length of value */
1414         len +                   /* n value */
1415         PAD (len);              /* p Pad(n) */
1416       value += len;
1417       total += len;
1418       attr_id_list += sizeof (CARD16);
1419       size -= sizeof (CARD16);
1420       num++;
1421     }
1422   *size_return = total;
1423   *num_return = num;
1424   return 0;
1425 }
1426 
1427 /*
1428  *    Function Name : EncodeICAttributes()
1429  *    Description   : encode IC attribute structure to byte data.
1430  *    Parameter     :
1431  *      attr_id_list: list of IC attribute id.
1432  *      size        : byte lenth of the list.
1433  *      xc          : pointer to client structure.
1434  *      value       : encoded byte data.
1435  *      size_return : returned byte length of the data.
1436  *    Returned Value:
1437  *      = 0         : successed.
1438  *      > 0         : error, the number is error code.
1439  */
1440 static int
EncodeICAttributes(attr_id_list,size,xc,value,size_return)1441 EncodeICAttributes (attr_id_list, size, xc, value, size_return)
1442      CARD8 *attr_id_list;
1443      int size;
1444      XIMClientRec *xc;
1445      CARD8 *value;
1446      int *size_return;
1447 {
1448   CARD8 *data;
1449   CARD16 *buf_16;
1450   CARD32 *buf_32;
1451   int ret, len, total, attr_id, num;
1452   int nested_size;
1453 
1454   ret = 0;
1455   total = 0;
1456   while (size > 0)
1457     {
1458       buf_16 = (CARD16 *) attr_id_list;
1459       attr_id = (int) GET_CARD16 (buf_16[0]);
1460       data = value + sizeof (CARD16) + sizeof (CARD16);
1461       buf_16 = (CARD16 *) data;
1462       buf_32 = (CARD32 *) data;
1463       switch (attr_id)
1464         {
1465         case ICInputStyle:
1466           len = sizeof (CARD32);
1467           buf_32[0] = GET_CARD32 (xc->input_style);
1468           break;
1469         case ICClientWindow:
1470           len = sizeof (CARD32);
1471           buf_32[0] = GET_CARD32 (xc->w);
1472           break;
1473         case ICFocusWindow:
1474           len = sizeof (CARD32);
1475           buf_32[0] = GET_CARD32 (xc->focus_window);
1476           break;
1477         case ICFilterEvents:
1478           len = sizeof (CARD32);
1479           buf_32[0] = GET_CARD32 (xc->filter_events);
1480           break;
1481         case ICPreeditAttributes:
1482           ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->pe), data, &len, &num);
1483           if (!ret)
1484             {
1485               nested_size = sizeof (CARD16) * num;
1486               attr_id_list += nested_size;
1487               size -= nested_size;
1488             }
1489           break;
1490         case ICStatusAttributes:
1491           ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->st), data, &len, &num);
1492           if (!ret)
1493             {
1494               nested_size = sizeof (CARD16) * num;
1495               attr_id_list += nested_size;
1496               size -= nested_size;
1497             }
1498           break;
1499         default:
1500           ret = XIM_BadProtocol;
1501         }
1502       if (ret)
1503         return ret;
1504       buf_16 = (CARD16 *) value;
1505       buf_16[0] = GET_CARD16 (attr_id);
1506       buf_16[1] = GET_CARD16 (len);
1507       len = sizeof (CARD16) +   /* 2 attribute-id */
1508         sizeof (CARD16) +       /* 2 byte length of value */
1509         len +                   /* n value */
1510         PAD (len);              /* p Pad(n) */
1511       value += len;
1512       total += len;
1513       attr_id_list += sizeof (CARD16);
1514       size -= sizeof (CARD16);
1515     }
1516   *size_return = total;
1517   return 0;
1518 }
1519 
1520 /*
1521  *    Function Name : DecodeIMAttributes()
1522  *    Description   : decode IM attributes.
1523  *    Parameter     :
1524  *      list        : list of IM attribute, packed data.
1525  *      size        : byte length of list.
1526  *      extension   : not used.
1527  *    Returned Value:
1528  *      = 0         : successed.
1529  *      > 0         : error, the number is error code.
1530  */
1531  /*ARGSUSED*/ static int
DecodeIMAttributes(list,size,extension)1532 DecodeIMAttributes (list, size, extension)
1533      CARD8 *list;
1534      int size;
1535      XPointer extension;        /* for extenstion in future */
1536 {
1537   CARD16 *buf_16;
1538   int ret, len, attr_id;
1539 
1540   ret = 0;
1541   while (size > 0)
1542     {
1543       buf_16 = (CARD16 *) list;
1544       attr_id = (int) GET_CARD16 (buf_16[0]);
1545       len = (int) GET_CARD16 (buf_16[1]);
1546       switch (attr_id)
1547         {
1548         case ICInputStyle:
1549           /* we don't allow to set InputStyle so far. */
1550           ret = XIM_BadStyle;
1551           break;
1552         default:
1553           /* no more supported so far */
1554           ret = XIM_BadSomething;
1555         }
1556       if (ret)
1557         return ret;
1558       len += sizeof (CARD16) +  /* 2 attribute-id */
1559         sizeof (CARD16) +       /* 2 n byte lenght of attr */
1560         len +                   /* n value of attr */
1561         PAD (len);              /* p Pad(n) */
1562       list += len;
1563       size -= len;
1564     }
1565   return 0;
1566 }
1567 
1568 /*
1569  *    Function Name : SetClientIMValues()
1570  *    Description   : decode IM values to client context.
1571  *    Parameter     :
1572  *      value       : IM values, packed data.
1573  *      size        : byte length of list.
1574  *      im          : client IM context.
1575  *    Returned Value:
1576  *      = 0         : successed.
1577  *      > 0         : error, the number is error code.
1578  */
1579 static int
SetClientIMValues(value,size,im)1580 SetClientIMValues (value, size, im)
1581      CARD8 *value;
1582      int size;
1583      XIMContextRec *im;
1584 {
1585   /* no any attribute can be set so far */
1586   return DecodeIMAttributes (value, size, (XPointer) NULL);
1587 }
1588 
1589 /*
1590  *    Function Name : EncodeInputStyleList()
1591  *    Description   : encode Input Style list to byte data.
1592  *    Parameter     :
1593  *      im          : pointer to client IM context.
1594  *      value       : encoded byte data.
1595  *      size_return : returned byte length of the data.
1596  *    Returned Value:
1597  *      = 0         : successed.
1598  *      > 0         : error, the number is error code.
1599  */
1600 static int
EncodeInputStyleList(im,value,size_return)1601 EncodeInputStyleList (im, value, size_return)
1602      XIMContextRec *im;
1603      CARD8 *value;
1604      int *size_return;
1605 {
1606   CARD16 *buf_16 = (CARD16 *) value;
1607   CARD32 *buf_32 = (CARD32 *) & buf_16[2];
1608   int num, i;
1609 
1610   num = MAX_SUPPORT_STYLE - 1;
1611   buf_16[0] = GET_CARD16 (num);
1612   for (i = 0; i <= num; i++)
1613     {
1614       buf_32[i] = GET_CARD32 (xim->supported_style[i]);
1615     }
1616   *size_return = sizeof (CARD16) +      /* 2 number of list */
1617     sizeof (CARD16) +           /* 2 unused */
1618     sizeof (CARD32) * MAX_SUPPORT_STYLE;
1619   return 0;
1620 }
1621 
1622 /*
1623  *    Function Name : EncodeIMAttributes()
1624  *    Description   : encode IM attribute structure to byte data.
1625  *    Parameter     :
1626  *      attr_id_list: list of attribute id.
1627  *      size        : byte length of the list.
1628  *      im          : pointer to client IM context.
1629  *      value       : encoded byte data.
1630  *      size_return : returned byte length of the data.
1631  *    Returned Value:
1632  *      = 0         : successed.
1633  *      > 0         : error, the number is error code.
1634  */
1635 static int
EncodeIMAttributes(attr_id_list,size,im,value,size_return)1636 EncodeIMAttributes (attr_id_list, size, im, value, size_return)
1637      CARD8 *attr_id_list;
1638      int size;
1639      XIMContextRec *im;
1640      CARD8 *value;
1641      int *size_return;
1642 {
1643   CARD8 *data;
1644   CARD16 *buf_16;
1645   int ret, len, total, attr_id;
1646 
1647   ret = 0;
1648   total = 0;
1649   while (size > 0)
1650     {
1651       buf_16 = (CARD16 *) attr_id_list;
1652       attr_id = (int) GET_CARD16 (buf_16[0]);
1653       data = value + sizeof (CARD16) + sizeof (CARD16);
1654       switch (attr_id)
1655         {
1656         case ICInputStyle:
1657           ret = EncodeInputStyleList (im, data, &len);
1658           break;
1659         default:
1660           ret = XIM_BadSomething;
1661         }
1662       if (ret)
1663         return ret;
1664       buf_16 = (CARD16 *) value;
1665       buf_16[0] = GET_CARD16 (attr_id);
1666       buf_16[1] = GET_CARD16 (len);
1667       len = sizeof (CARD16) +   /* 2 attribute-id */
1668         sizeof (CARD16) +       /* 2 byte length of value */
1669         len +                   /* n value */
1670         PAD (len);              /* p Pad(n) */
1671       value += len;
1672       total += len;
1673       attr_id_list += sizeof (CARD16);
1674       size -= sizeof (CARD16);
1675     }
1676   *size_return = total;
1677   return 0;
1678 }
1679 
1680 /*
1681  *    Function Name : CreateClientIC()
1682  *    Description   : create an IC context and assign a new IC id.
1683  *    Parameter     :
1684  *      im_id       : client input-method-id.
1685  *      list        : list of IC attributes, packed data.
1686  *      size        : byte length of list.
1687  *      ic_id_return: new IC id of the create IC context.
1688  *    Returned Value:
1689  *      = 0         : successed.
1690  *      > 0         : error, the number is error code.
1691  */
1692 static int
CreateClientIC(im_id,list,size,ic_id_return)1693 CreateClientIC (im_id, list, size, ic_id_return)
1694      XIMID im_id;
1695      CARD8 *list;
1696      int size;
1697      XICID *ic_id_return;
1698 {
1699   XIMClientRec *xc;
1700   ximICValuesReq ic_req;
1701   ximICAttributesReq pre_req, st_req;
1702   char *pre_font = (char *) NULL;
1703   char *st_font = (char *) NULL;
1704   XIMNestLangList lc_list = (XIMNestLangList) NULL;
1705   XIMNestLangList cur_lc = (XIMNestLangList) NULL;
1706   XIMNestLangList p;
1707   int have_world = 0, cur_is_world = 0;
1708   char *use_langs, *cur_l, *c_data;
1709   int xic, ret, i;
1710   short detail;
1711   extern XIMClientRec *create_client ();
1712 
1713   /*
1714    * parse attributes
1715    */
1716   ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
1717   if (ret)
1718     return ret;
1719   ic_req.max_keycode = 0;       /* set 0 as default */
1720 
1721   use_langs = cur_use_lang;     /* use locale from XIM_OPEN */
1722   cur_l = (char *) NULL;        /* current lang not specified yet. */
1723   c_data = (char *) NULL;       /* default user name. */
1724 
1725   /* refer to util.c: CreateIC() */
1726 
1727   /*
1728    * check resources.
1729    */
1730   if (CheckInputStyle (ic_req.input_style) == False)
1731     return XIM_BadStyle;
1732   if ((ic_req.input_style & (XIMPreeditArea | XIMPreeditPosition)) && (!(ic_req.mask & (1 << ICFontSet)) || !pre_font || !*pre_font))
1733     return XIM_BadName;
1734   if ((ic_req.input_style & XIMStatusArea) && (!(ic_req.mask & (1 << (ICFontSet + StatusOffset))) || !st_font || !*st_font))
1735     return XIM_BadName;
1736   if ((ic_req.input_style & XIMPreeditPosition) && (!(ic_req.mask & (1 << ICSpotLocation))))
1737     return XIM_BadSpotLocation;
1738   if (!(ic_req.input_style & XIMPreeditNothing))
1739     {
1740       if ((have_world = get_langlist (use_langs, &lc_list)) < 0)
1741         {
1742           return XIM_BadAlloc;
1743         }
1744       if (!lc_list)
1745         {
1746           return XIM_LocaleNotSupported;
1747         }
1748       if (cur_l && *cur_l)
1749         {
1750           for (p = lc_list; p != NULL; p = p->next)
1751             {
1752               if (!strcmp (p->lc_name, cur_l) || (p->alias_name && !strcmp (p->alias_name, cur_l)))
1753                 break;
1754             }
1755           if (p == NULL)
1756             {
1757               if ((i = get_langlist (cur_l, &cur_lc)) < 0)
1758                 {
1759                   return XIM_BadAlloc;
1760                 }
1761               else if (i > 0)
1762                 {
1763                   cur_is_world++;
1764                   free_langlist (cur_lc);
1765                   cur_lc = lc_list;
1766                 }
1767               else
1768                 {
1769                   if (cur_lc)
1770                     {
1771                       cur_lc->next = lc_list;
1772                     }
1773                   else
1774                     {
1775                       cur_lc = lc_list;
1776                     }
1777                 }
1778             }
1779           else
1780             {
1781               cur_lc = p;
1782             }
1783         }
1784       else
1785         {
1786           if (have_world == 2)
1787             cur_is_world++;
1788           cur_lc = lc_list;
1789         }
1790     }
1791   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);
1792   if (pre_font)
1793     XFree (pre_font);
1794   if (st_font)
1795     XFree (st_font);
1796   if (lc_list)
1797     free_langlist (lc_list);
1798   if (!xc)
1799     {
1800       return ConvErrorCode (detail);
1801     }
1802   xic = xim->client_count++;
1803   xc->number = xic;
1804   xc->im_id = (int) im_id;
1805   if (IsPreeditNothing (xc))
1806     {
1807       check_root_mapping (xc->root_pointer);
1808     }
1809 
1810   *ic_id_return = (XICID) xic;
1811   return 0;
1812 }
1813 
1814 /*
1815  *    Function Name : CreateIM()
1816  *    Description   : create a new IM context and register in the list.
1817  *    Parameter     :
1818  *      <none>
1819  *    Returned Value:
1820  *      > 0         : IM id of the new IM context created.
1821  *      = 0         : error
1822  */
1823 static XIMID
CreateIM()1824 CreateIM ()
1825 {
1826   static XIMID base_im_id = BASE_IM_ID;
1827   XIMContextRec *im;
1828 
1829   im = (XIMContextRec *) Malloc (sizeof (XIMContextRec));
1830   if (!im)
1831     {
1832       malloc_error ("no memory to open an IM");
1833       return 0;
1834     }
1835   im->im_id = ALLOC_ID (base_im_id);
1836 
1837   /* add to IM list */
1838   im->next = ximlist;
1839   ximlist = im;
1840   return im->im_id;
1841 }
1842 
1843 /*
1844  *    Function Name : GetCompoundTextIndex()
1845  *    Description   : search the index of string named COMPOUND_TEXT in
1846  *                    LISTofSTR.
1847  *    Parameter     :
1848  *      list        : list of string names LISTofSTR.
1849  *      size        : byte length of the list.
1850  *    Returned Value:
1851  *      int         : returned index in this list. If not found, it is
1852  *                    the default XIM_Default_Encoding_IDX.
1853  */
1854 static int
GetCompoundTextIndex(list,size)1855 GetCompoundTextIndex (list, size)
1856      register CARD8 *list;
1857      register int size;
1858 {
1859   register int index, len;
1860 
1861   /* get index of COMPOUNT_TEXT which is only supported by us. */
1862   index = 0;
1863   while (size > 0)
1864     {
1865       len = (int) list[0];
1866       if (!strncmp (&list[1], "COMPOUND_TEXT", len))
1867         break;
1868       index++;
1869       list += (sizeof (CARD8) + len);
1870       size -= (sizeof (CARD8) + len);
1871     };
1872   if (size == 0)
1873     index = XIM_Default_Encoding_IDX;   /* use default */
1874   return index;
1875 }
1876 
1877 /*
1878  *    Function Name : FindExtensionByName()
1879  *    Description   : search an extension item with its name in extension
1880  *                    list supported by this server.
1881  *    Parameter     :
1882  *      name        : ext string name.
1883  *      len         : length of ext name.
1884  *    Returned Value:
1885  *      >= 0        : found item index to this list.
1886  *      = -1        : not found.
1887  */
1888 static int
FindExtensionByName(name,len)1889 FindExtensionByName (name, len)
1890      char *name;
1891      int len;
1892 {
1893   int ind;
1894 
1895   for (ind = 0; ind < XIMNumber (extension_list); ind++)
1896     {
1897       if (!strncmp (extension_list[ind].name, name, len))
1898         return ind;
1899     }
1900   return -1;
1901 }
1902 
1903 /*
1904  *    Function Name : EncodeExtension()
1905  *    Description   : encode an extension item to byte data.
1906  *    Parameter     :
1907  *      ind         : the item index to extension list.
1908  *      value       : byte data to store the packed ext item.
1909  *      size_return : returned byte size of the packed ext item
1910  *    Returned Value:
1911  *      = 0         : successed.
1912  *      > 0         : error, the number is error code.
1913  */
1914 static int
EncodeExtension(ind,value,size_return)1915 EncodeExtension (ind, value, size_return)
1916      int ind;
1917      CARD8 *value;
1918      int *size_return;
1919 {
1920   CARD16 *buf_16 = (CARD16 *) & value[2];
1921   int len;
1922 
1923   len = strlen (extension_list[ind].name);
1924   value[0] = extension_list[ind].major_code;
1925   value[1] = extension_list[ind].minor_code;
1926   buf_16[0] = GET_CARD16 (len);
1927   (void) strncpy ((char *) &buf_16[1], extension_list[ind].name, len);
1928   *size_return = sizeof (CARD8) +       /* 1 major_code */
1929     sizeof (CARD8) +            /* 1 minor_code */
1930     sizeof (CARD16) +           /* 2 n length of name */
1931     len +                       /* n name */
1932     PAD (len);                  /* p Pad(n) */
1933   return 0;
1934 }
1935 
1936 /*
1937  *    Function Name : GetExtensionList()
1938  *    Description   : get extensions supported by the server.
1939  *    Parameter     :
1940  *      list        : list of extension names asked by client.
1941  *      size        : byte length of the list, if it is zero, client asks
1942  *                    all extensions supported by the server.
1943  *      value       : the returned exension names supported by server. It is
1944  *                    packed in byte.
1945  *      size_return : returned byte size of the packed ext names.
1946  *    Returned Value:
1947  *      = 0         : successed.
1948  *      > 0         : error, the number is error code.
1949  */
1950 static int
GetExtensionList(list,size,value,size_return)1951 GetExtensionList (list, size, value, size_return)
1952      CARD8 *list;
1953      int size;
1954      CARD8 *value;
1955      int *size_return;
1956 {
1957   int len, ext_len, ind, total;
1958 
1959   total = 0;
1960   if (size == 0)
1961     {
1962       for (ind = 0; ind < XIMNumber (extension_list); ind++)
1963         {
1964           (void) EncodeExtension (ind, value, &ext_len);
1965           value += ext_len;
1966           total += ext_len;
1967         }
1968     }
1969   else
1970     {
1971       while (size > 0)
1972         {
1973           len = (int) list[0];
1974           if ((ind = FindExtensionByName ((char *) &list[1], len)) >= 0)
1975             {
1976               (void) EncodeExtension (ind, value, &ext_len);
1977               value += ext_len;
1978               total += ext_len;
1979             }
1980           list += (sizeof (CARD8) + len);
1981           size -= (sizeof (CARD8) + len);
1982         }
1983     }
1984   *size_return = total;
1985   return 0;
1986 }
1987 
1988 /*
1989  *    Function Name : RecvRequest()
1990  *    Description   : receive a request of XIM protocol from IM library.
1991  *    Parameter     :
1992  *      req         : pointer to a request structure, returned.
1993  *    Returned Value:
1994  *      >=0         : byte length of request data except request head.
1995  *      < 0         : error in reading data.
1996  */
1997 static int
RecvRequest(req)1998 RecvRequest (req)
1999      XimRequestPacket *req;
2000 {
2001   CARD8 *buf, *read_ptr;
2002   CARD8 byteOrder;
2003   int read_size;
2004   extern char my_byteOrder;
2005 
2006   if (_ReadFromClient ((char *) req, XIM_HEADER_SIZE) == -1)
2007     return -1;
2008   if (req->length == 0)
2009     return 0;
2010   read_size = req->length * 4;
2011   read_ptr = buf = MALLOC_REQUEST (read_size);
2012   bzero ((char *) buf, read_size);
2013   if (req->major_opcode == XIM_CONNECT)
2014     {
2015       _ReadFromClient ((char *) &byteOrder, 1);
2016       if (my_byteOrder != (char) byteOrder)
2017         cur_cblk->byteOrder = True;
2018       else
2019         cur_cblk->byteOrder = False;
2020       buf[0] = byteOrder;
2021       read_ptr = &buf[1];
2022       read_size--;
2023     }
2024   if (_ReadFromClient (read_ptr, read_size) == -1)
2025     {
2026       FREE (buf);
2027       return -1;
2028     }
2029   req->data = buf;
2030   return req->length * 4;
2031 }
2032 
2033 /*
2034  *    Function Name : SendIdOnly()
2035  *    Description   : send a request that is the format of:
2036  *                        CARD16 input-method-id
2037  *                        CARD16 input-context-id
2038  *    Parameter     :
2039  *      im_id       : client input-method-id.
2040  *      ic_id       : client input-context-id.
2041  *      major_code  : major opcode of this request.
2042  *      minor_code  : minor opcode of this request.
2043  *    Returned Value:
2044  *      = 0         : successed.
2045  *      > 0         : error, the number is error code.
2046  */
2047 static int
SendIdOnly(im_id,ic_id,major_code,minor_code)2048 SendIdOnly (im_id, ic_id, major_code, minor_code)
2049      XIMID im_id;
2050      XICID ic_id;
2051      CARD8 major_code;
2052      CARD8 minor_code;
2053 {
2054   CARD16 *buf_16;
2055   CARD8 *reply;
2056   int len;
2057 
2058   /* reply */
2059   len = sizeof (CARD16) +       /* 2 input-method-ID */
2060     sizeof (CARD16);            /* 2 input-context-ID */
2061   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2062   len += AddHead (reply, major_code, minor_code, len);
2063   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2064   buf_16[0] = GET_CARD16 (im_id);
2065   buf_16[1] = GET_CARD16 (ic_id);
2066   if (_WriteToClientFlush (reply, len) < 0)
2067     {
2068       FREE (reply);
2069       return XIM_BadSomething;
2070     }
2071   FREE (reply);
2072   return 0;
2073 }
2074 
2075 /*
2076  *    Function Name : SendSyncReply()
2077  *    Description   : If server has not syncronized, do sync. Then
2078  *                    send a XIM_SYNC_REPLY to IM library.
2079  *    Parameter     :
2080  *      im_id       : client input-method-id.
2081  *      ic_id       : client input-context-id.
2082  *    Returned Value:
2083  *      = 0         : successed.
2084  *      > 0         : error, the number is error code.
2085  */
2086 static int
SendSyncReply(im_id,ic_id)2087 SendSyncReply (im_id, ic_id)
2088      XIMID im_id;
2089      XICID ic_id;
2090 {
2091   if (!AllSyncDone (im_id, ic_id))
2092     {
2093       SyncAll (im_id, ic_id);
2094     }
2095   return SendIdOnly (im_id, ic_id, XIM_SYNC_REPLY, 0);
2096 }
2097 
2098 /*
2099  *    Function Name : RecvSync()
2100  *    Description   : process of client request XIM_SYNC.
2101  *    Parameter     :
2102  *      req         : pointer to a request structure.
2103  *    Returned Value:
2104  *      = 0         : successed.
2105  *      > 0         : error, the number is error code.
2106  */
2107 static int
RecvSync(req)2108 RecvSync (req)
2109      XimRequestPacket *req;
2110 {
2111   CARD16 *buf_16 = (CARD16 *) req->data;
2112   XIMID im_id;
2113   XICID ic_id;
2114 
2115   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2116   if (!GetIMWithId (im_id))
2117     return XIM_BadProtocol;
2118 
2119   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
2120   if (!GetICWithId (ic_id))
2121     return XIM_BadProtocol;
2122 
2123   return SendSyncReply (im_id, ic_id);
2124 }
2125 
2126 /*
2127  *    Function Name : RecvSyncReply()
2128  *    Description   : process of client request XIM_SYNC_REPLY.
2129  *    Parameter     :
2130  *      req         : pointer to a request structure.
2131  *    Returned Value:
2132  *      = 0         : successed.
2133  *      > 0         : error, the number is error code.
2134  */
2135 static int
RecvSyncReply(req)2136 RecvSyncReply (req)
2137      XimRequestPacket *req;
2138 {
2139   /* no action. */
2140   return 0;
2141 }
2142 
2143 /*
2144  *    Function Name : RecvError()
2145  *    Description   : process of client request XIM_ERROR.
2146  *    Parameter     :
2147  *      req         : pointer to a request structure.
2148  *    Returned Value:
2149  *      = 0         : successed.
2150  *      > 0         : error, the number is error code.
2151  */
2152 static int
RecvError(req)2153 RecvError (req)
2154      XimRequestPacket *req;
2155 {
2156   CARD16 *buf_16 = (CARD16 *) req->data;
2157   XIMID im_id;                  /* not used yet */
2158   XICID ic_id;                  /* not used yet */
2159   int eflag, ecode, esnum;
2160 
2161   im_id = (XIMID) GET_CARD16 (buf_16[0]);       /* 2 input-method-ID */
2162   ic_id = (XICID) GET_CARD16 (buf_16[1]);       /* 2 input-context-ID */
2163   eflag = (int) GET_CARD16 (buf_16[2]); /* 2 flag */
2164   ecode = (int) GET_CARD16 (buf_16[3]); /* 2 error code */
2165   esnum = (int) GET_CARD16 (buf_16[4]); /* 2 n length */
2166   if (esnum > 0)
2167     {
2168       char *emsg;
2169       if (!(emsg = Malloc (esnum + 1)))
2170         {
2171           return XIM_BadAlloc;
2172         }
2173       (void) strncpy (emsg, (char *) &buf_16[6], esnum);
2174       emsg[esnum] = '\0';
2175       print_out3 ("XIM Protocol Error: %d %s\n", ecode, emsg);
2176       XFree (emsg);
2177     }
2178   else
2179     {
2180       print_out2 ("XIM Protocol Error: %d\n", ecode);
2181     }
2182   return 0;
2183 }
2184 
2185 /*
2186  *    Function Name : SendError()
2187  *    Description   : send error message to IM library with the request
2188  *                    XIM_ERROR.
2189  *    Parameter     :
2190  *      err_code    : error code.
2191  *    Returned Value:
2192  *      <none>
2193  */
2194 static void
SendError(err_code)2195 SendError (err_code)
2196      CARD16 err_code;
2197 {
2198   CARD16 *buf_16;
2199   CARD8 *reply;
2200   int len;
2201 
2202   len = sizeof (CARD16) +       /* 2 input-method-ID */
2203     sizeof (CARD16) +           /* 2 input-context-ID */
2204     sizeof (BITMASK16) +        /* 2 flag */
2205     sizeof (CARD16) +           /* 2 error code */
2206     sizeof (INT16) +            /* 2 byte length of error detail */
2207     sizeof (CARD16);            /* 2 type of error detail */
2208 /* empty *//* n error detail */
2209 
2210   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2211   len += AddHead (reply, XIM_ERROR, 0, len);
2212   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2213   buf_16[0] = GET_CARD16 (cur_im_id);
2214   buf_16[1] = GET_CARD16 (cur_ic_id);
2215   buf_16[2] = GET_CARD16 (cur_status);
2216   buf_16[3] = GET_CARD16 (err_code);
2217   buf_16[4] = 0;                /* no error detail */
2218   buf_16[5] = 0;                /* no type */
2219   (void) _WriteToClientFlush (reply, len);
2220   FREE (reply);
2221 }
2222 
2223 /*
2224  *    Function Name : SendAuthRequired()
2225  *    Description   : reply XIM_AUTH_REQUIRED as client ask auth.
2226  *    Parameter     :
2227  *      auth_index  : index of list of auth names.
2228  *      auth_data   : auth data.
2229  *      length_data : byte length of data.
2230  *    Returned Value:
2231  *      = 0         : successed.
2232  *      > 0         : error, the number is error code.
2233  */
2234 static int
SendAuthRequired(auth_index,auth_data,length_data)2235 SendAuthRequired (auth_index, auth_data, length_data)
2236      CARD8 auth_index;
2237      CARD8 *auth_data;
2238      INT16 length_data;
2239 {
2240   CARD8 *buf_8;
2241   CARD16 *buf_16;
2242   CARD8 *reply;
2243   int len;
2244 
2245   len = sizeof (CARD8) +        /* 1 auth-protocol_index */
2246     sizeof (CARD8) * 3 +        /* 3 unused */
2247     sizeof (CARD16) +           /* 2 length of auth data */
2248     sizeof (CARD16) +           /* 2 unused */
2249     length_data +               /* n data */
2250     PAD (length_data);          /* p unused, p = Pad(n) */
2251 
2252   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2253   len += AddHead (reply, XIM_AUTH_REQUIRED, 0, len);
2254   buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE);
2255   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4);
2256   buf_8[0] = (CARD8) auth_index;
2257   buf_16[0] = GET_CARD16 (length_data);
2258   if (auth_data && length_data > 0)
2259     {
2260       buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4 + sizeof (CARD16) * 2);
2261       memcpy ((char *) buf_8, (char *) auth_data, length_data);
2262     }
2263   if (_WriteToClientFlush (reply, len) < 0)
2264     {
2265       FREE (reply);
2266       return XIM_BadSomething;
2267     }
2268   FREE (reply);
2269   return 0;
2270 }
2271 
2272 /*
2273  *    Function Name : SendConnectReply()
2274  *    Description   : reply connection from IM library.
2275  *    Parameter     :
2276  *      major_version
2277  *                  : major version of XIM protocol
2278  *      minor_version
2279  *                  : minor version of XIM protocol
2280  *    Returned Value:
2281  *      = 0         : successed.
2282  *      > 0         : error, the number is error code.
2283  */
2284 static int
SendConnectReply(major_version,minor_version)2285 SendConnectReply (major_version, minor_version)
2286      CARD16 major_version;
2287      CARD16 minor_version;
2288 {
2289   CARD16 *buf_16;
2290   CARD8 *reply;
2291   int len;
2292 
2293   len = sizeof (CARD16) +       /* 2 server-major-protocol-version */
2294     sizeof (CARD16);            /* 2 server-minor-protocol-version */
2295   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2296   len += AddHead (reply, XIM_CONNECT_REPLY, 0, len);
2297   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2298   buf_16[0] = GET_CARD16 (major_version);
2299   buf_16[1] = GET_CARD16 (minor_version);
2300   if (_WriteToClientFlush (reply, len) < 0)
2301     {
2302       FREE (reply);
2303       return XIM_BadSomething;
2304     }
2305   FREE (reply);
2306   return 0;
2307 }
2308 
2309 /*
2310  *    Function Name : RecvConnect()
2311  *    Description   : do connection with IM client.
2312  *    Parameter     :
2313  *      req         : pointer to a request structure.
2314  *    Returned Value:
2315  *      = 0         : successed.
2316  *      > 0         : error, the number is error code.
2317  */
2318 static int
RecvConnect(req)2319 RecvConnect (req)
2320      XimRequestPacket *req;
2321 {
2322   CARD16 *buf_16 = (CARD16 *) (req->data + 2);
2323   CARD16 major_version, minor_version, auth_num;
2324   int len;
2325 
2326   len = req->length * 4;
2327 /* we have touched in RecvRequest *//* 1 byte order */
2328 /* not used *//* 1 unused */
2329   major_version = GET_CARD16 (buf_16[0]);       /* 2 major protocol version */
2330   minor_version = GET_CARD16 (buf_16[1]);       /* 2 minor protocol version */
2331   auth_num = GET_CARD16 (buf_16[2]);    /* 2 number of auth. names */
2332 
2333   if (major_version != PROTOCOLMAJORVERSION || minor_version != PROTOCOLMINORVERSION)
2334     return XIM_BadProtocol;
2335 
2336   len -= sizeof (CARD8) + sizeof (CARD8) + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16);
2337 
2338   if (auth_num > 0)
2339     {
2340       if (GetAuth (&buf_16[3], auth_num, &len, NULL) == False)
2341         {
2342           return XIM_BadSomething;      /* error in get auth. */
2343         }
2344       return SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
2345     }
2346   else
2347     {
2348       return SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
2349     }
2350 }
2351 
2352 /*
2353  *    Function Name : RecvDisconnect()
2354  *    Description   : disconnect with IM client.
2355  *    Parameter     :
2356  *      req         : pointer to a request structure.
2357  *    Returned Value:
2358  *      = 0         : successed.
2359  *      > 0         : error, the number is error code.
2360  */
2361 static int
RecvDisconnect(req)2362 RecvDisconnect (req)
2363      XimRequestPacket *req;
2364 {
2365   CARD8 *reply;
2366   int len;
2367   extern int cur_sock;
2368 
2369   close_socket (cur_sock);
2370 
2371   /* reply */
2372   len = 0;                      /* no data */
2373   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2374   len += AddHead (reply, XIM_DISCONNECT_REPLY, 0, len);
2375   if (_WriteToClientFlush (reply, len) < 0)
2376     {
2377       FREE (reply);
2378       return XIM_BadSomething;
2379     }
2380   FREE (reply);
2381   return 0;
2382 }
2383 
2384 #ifdef DYNAMIC_EVENT_FLOW_MODEL
2385 
2386 /*
2387  *    Function Name : SendRegisterTriggerKeys()
2388  *    Description   : ask client to register trigger keys which will
2389  *                    turn on or off input method.
2390  *    Parameter     :
2391  *      im_id       : client input-method-id.
2392  *    Returned Value:
2393  *      <none>
2394  */
2395 static void
SendRegisterTriggerKeys(im_id)2396 SendRegisterTriggerKeys (im_id)
2397      XIMID im_id;
2398 {
2399   CARD8 *reply;
2400   CARD16 *buf_16;
2401   CARD32 *buf_32;
2402   CARD32 onkeys[3];
2403   int onkeys_len;
2404   int len;
2405 
2406   onkeys[0] = GET_CARD32 (trigger_keys_list[0]);
2407   onkeys[1] = GET_CARD32 (trigger_keys_list[1]);
2408   onkeys[2] = GET_CARD32 (trigger_keys_list[2]);
2409   onkeys_len = sizeof (CARD32) * 3;
2410 
2411   /* send */
2412   len = sizeof (CARD16) +       /* 2 input-method-ID */
2413     sizeof (CARD16) +           /* 2 unused */
2414     sizeof (CARD32) +           /* 4 n byte length */
2415     onkeys_len +                /* n LISTofXIMTRIGGERKEY */
2416     sizeof (CARD32) +           /* 4 m byte length */
2417     onkeys_len;                 /* m LISTofXIMTRIGGERKEY */
2418 
2419   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2420   len += AddHead (reply, XIM_REGISTER_TRIGGERKEYS, 0, len);
2421   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2422   buf_16[0] = GET_CARD16 (im_id);
2423   buf_32 = (CARD32 *) & buf_16[2];
2424   buf_32[0] = GET_CARD32 (onkeys_len);
2425   (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
2426   buf_32 = (CARD32 *) (reply + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD32) + onkeys_len);
2427   buf_32[0] = GET_CARD32 (onkeys_len);  /* off keys same as on-keys */
2428   (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
2429   (void) _WriteToClientFlush (reply, len);
2430   FREE (reply);
2431 }
2432 
2433 /*
2434  *    Function Name : ToggleHenkan()
2435  *    Description   : turn on or off kanji henkan.
2436  */
2437 static void
ToggleHenkan(keys_index,mask)2438 ToggleHenkan (keys_index, mask)
2439      int keys_index;
2440      unsigned long mask;
2441 {
2442   /* not yet */
2443 }
2444 
2445 /*
2446  *    Function Name : RecvTriggerNotify()
2447  *    Description   : Some trigger key has pressed by client, it means
2448  *                    client asks some input method. do it.
2449  *    Parameter     :
2450  *      req         : pointer to a request structure.
2451  *    Returned Value:
2452  *      = 0         : successed.
2453  *      > 0         : error, the number is error code.
2454  */
2455 static int
RecvTriggerNotify(req)2456 RecvTriggerNotify (req)
2457      XimRequestPacket *req;
2458 {
2459   CARD16 *buf_16 = (CARD16 *) req->data;
2460   CARD32 *buf_32;
2461   CARD8 *reply;
2462   XIMID im_id;
2463   XICID ic_id;
2464   int len;
2465   int ret, n;
2466   int keys_flag, keys_index;
2467   unsigned long mask;
2468   XIMClientRec *xc;
2469 
2470   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2471   if (!GetIMWithId (im_id))
2472     return XIM_BadProtocol;
2473 
2474   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
2475   if (!(xc = GetICWithId (ic_id)))
2476     return XIM_BadProtocol;
2477 
2478   buf_32 = (CARD32 *) & buf_16[2];
2479   keys_flag = (int) GET_CARD32 (buf_32[0]);
2480   keys_index = (int) GET_CARD32 (buf_32[1]);
2481   mask = (unsigned long) GET_CARD32 (buf_32[2]);
2482 
2483   if (!keys_flag)
2484     {
2485       /* trigger on */
2486       ToggleHenkan (keys_index, mask);
2487     }
2488   else
2489     {
2490       /* trigger off */
2491       ToggleHenkan (keys_index, mask);
2492     }
2493 
2494   /* reply */
2495   return SendIdOnly (im_id, ic_id, XIM_TRIGGER_NOTIFY_REPLY, 0);
2496 }
2497 
2498 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
2499 
2500 /*
2501  *    Function Name : RecvOpen()
2502  *    Description   : open an IM context for client.
2503  *    Parameter     :
2504  *      req         : pointer to a request structure.
2505  *    Returned Value:
2506  *      = 0         : successed.
2507  *      > 0         : error, the number is error code.
2508  */
2509 static int
RecvOpen(req)2510 RecvOpen (req)
2511      XimRequestPacket *req;
2512 {
2513   CARD8 *reply;
2514   CARD16 *buf_16;
2515   XIMID im_id;
2516   int len;
2517 
2518   if (_CheckLocaleName (req->data, cur_use_lang) == False)
2519     return XIM_LocaleNotSupported;
2520 
2521   if (!(im_id = CreateIM ()))
2522     return XIM_BadAlloc;
2523 
2524 #ifdef DYNAMIC_EVENT_FLOW_MODEL
2525   SendRegisterTriggerKeys (im_id);
2526 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
2527 
2528   /* reply */
2529   len = sizeof (CARD16) +       /* 2 input-method-id */
2530     sizeof (CARD16) +           /* 2 byte length of IM attr. */
2531     imattr_list_size +          /* n IM attr. supported */
2532     sizeof (CARD16) +           /* 2 byte length of IC attr. */
2533     sizeof (CARD16) +           /* 2 unused */
2534     icattr_list_size;           /* m IC attr. supported */
2535   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2536   len += AddHead (reply, XIM_OPEN_REPLY, 0, len);
2537   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2538   buf_16[0] = GET_CARD16 (im_id);
2539   buf_16[1] = GET_CARD16 (imattr_list_size);
2540   memcpy ((char *) &buf_16[2], (char *) imattr_list, imattr_list_size);
2541 
2542   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD16) + sizeof (CARD16) + imattr_list_size);
2543   buf_16[0] = GET_CARD16 (icattr_list_size);
2544   memcpy ((char *) &buf_16[2], (char *) icattr_list, icattr_list_size);
2545 
2546   if (_WriteToClientFlush (reply, len) < 0)
2547     {
2548       FREE (reply);
2549       return XIM_BadSomething;
2550     }
2551   FREE (reply);
2552   return 0;
2553 }
2554 
2555 /*
2556  *    Function Name : RecvClose()
2557  *    Description   : close an IM client.
2558  *    Parameter     :
2559  *      req         : pointer to a request structure.
2560  *    Returned Value:
2561  *      = 0         : successed.
2562  *      > 0         : error, the number is error code.
2563  */
2564 static int
RecvClose(req)2565 RecvClose (req)
2566      XimRequestPacket *req;
2567 {
2568   CARD16 *buf_16 = (CARD16 *) req->data;
2569   CARD8 *reply;
2570   XIMID im_id;
2571   int len;
2572 
2573   im_id = cur_im_id = GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2574   if (RemoveIMWithId (im_id) == False)
2575     return XIM_BadProtocol;
2576   cur_im_id = 0;
2577 
2578   /* reply */
2579   len = sizeof (CARD16) +       /* 2 input-method-ID */
2580     sizeof (CARD16);            /* 2 unused */
2581   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2582   len += AddHead (reply, XIM_CLOSE_REPLY, 0, len);
2583   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2584   buf_16[0] = GET_CARD16 (im_id);
2585   if (_WriteToClientFlush (reply, len) < 0)
2586     {
2587       FREE (reply);
2588       return XIM_BadSomething;
2589     }
2590   FREE (reply);
2591   return 0;
2592 }
2593 
2594 /*
2595  *    Function Name : RecvQueryExtension()
2596  *    Description   : send extension lists supported by server as the
2597  *                    client asks.
2598  *    Parameter     :
2599  *      req         : pointer to a request structure.
2600  *    Returned Value:
2601  *      = 0         : successed.
2602  *      > 0         : error, the number is error code.
2603  */
2604 static int
RecvQueryExtension(req)2605 RecvQueryExtension (req)
2606      XimRequestPacket *req;
2607 {
2608   CARD16 *buf_16 = (CARD16 *) (req->data);
2609   CARD8 *reply;
2610   XIMID im_id;
2611   CARD8 value[BUFSIZ];
2612   int len, value_len;
2613   int ret, n;
2614 
2615   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2616   if (!GetIMWithId (im_id))
2617     {
2618       return XIM_BadProtocol;
2619     }
2620 
2621   /* get extetions supported by us. */
2622   n = GET_CARD16 (buf_16[1]);   /* 2 n byte length */
2623   ret = GetExtensionList ((CARD8 *) & buf_16[2], n, value, &value_len);
2624   if (ret)
2625     return ret;
2626 
2627   /* reply */
2628   len = sizeof (CARD16) +       /* 2 input-method-ID */
2629     sizeof (CARD16) +           /* 2 n byte length */
2630     value_len;                  /* n LISTofEXT */
2631   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2632   len += AddHead (reply, XIM_QUERY_EXTENSION_REPLY, 0, len);
2633   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2634   buf_16[0] = GET_CARD16 (im_id);
2635   buf_16[1] = GET_CARD16 (value_len);
2636   (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
2637   if (_WriteToClientFlush (reply, len) < 0)
2638     {
2639       FREE (reply);
2640       return XIM_BadSomething;
2641     }
2642   FREE (reply);
2643   return 0;
2644 }
2645 
2646 /*
2647  *    Function Name : RecvEncodingNegotiation()
2648  *    Description   : decide COMPOUND_TEXT as the result of encoding
2649  *                    negotiation between IM client and server.
2650  *    Parameter     :
2651  *      req         : pointer to a request structure.
2652  *    Returned Value:
2653  *      = 0         : successed.
2654  *      > 0         : error, the number is error code.
2655  */
2656 static int
RecvEncodingNegotiation(req)2657 RecvEncodingNegotiation (req)
2658      XimRequestPacket *req;
2659 {
2660   CARD16 *buf_16 = (CARD16 *) req->data;
2661   CARD8 *reply;
2662   XIMID im_id;
2663   int len, n, index;
2664 
2665   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2666   if (!GetIMWithId (im_id))
2667     return XIM_BadProtocol;
2668 
2669   /* we care only the index of COMPOUNT_TEXT */
2670   n = GET_CARD16 (buf_16[1]);   /* 2 byte length */
2671   index = GetCompoundTextIndex ((CARD8 *) & buf_16[2], n);
2672 
2673   /* reply */
2674   len = sizeof (CARD16) +       /* 2 input-method-ID */
2675     sizeof (CARD16) +           /* 2 category of the encoding */
2676     sizeof (CARD16) +           /* 2 index of the encoding */
2677     sizeof (CARD16);            /* 2 unused */
2678   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2679   len += AddHead (reply, XIM_ENCODING_NEGOTIATION_REPLY, 0, len);
2680   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2681   buf_16[0] = GET_CARD16 (im_id);
2682   buf_16[1] = GET_CARD16 (XIM_Encoding_NameCategory);
2683   buf_16[2] = GET_CARD16 (index);
2684   if (_WriteToClientFlush (reply, len) < 0)
2685     {
2686       FREE (reply);
2687       return XIM_BadSomething;
2688     }
2689   FREE (reply);
2690   return 0;
2691 }
2692 
2693 /*
2694  *    Function Name : SendSetEventMask()
2695  *    Description   : send XEvent mask to client which will foward any
2696  *                    event to the server.
2697  *    Parameter     :
2698  *      req         : pointer to a request structure.
2699  *    Returned Value:
2700  *      <none>
2701  */
2702 static void
SendSetEventMask(im_id,ic_id)2703 SendSetEventMask (im_id, ic_id)
2704      XIMID im_id;
2705      XICID ic_id;
2706 {
2707   CARD8 *reply;
2708   CARD16 *buf_16;
2709   CARD32 *buf_32;
2710   int len;
2711 
2712   /* send */
2713   len = sizeof (CARD16) +       /* 2 input-method-ID */
2714     sizeof (CARD16) +           /* 2 input-context-ID */
2715     sizeof (BITMASK32) +        /* 4 forw-event-mask */
2716     sizeof (BITMASK32);         /* 4 sync-event-mask */
2717   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2718   len += AddHead (reply, XIM_SET_EVENT_MASK, 0, len);
2719   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2720   buf_16[0] = GET_CARD16 (im_id);
2721   buf_16[1] = GET_CARD16 (ic_id);
2722   buf_32 = (CARD32 *) & buf_16[2];
2723   buf_32[0] = (KeyPressMask | StructureNotifyMask);
2724   buf_32[1] = (KeyPressMask | StructureNotifyMask);
2725   (void) _WriteToClientFlush (reply, len);
2726   FREE (reply);
2727 }
2728 
2729 /*
2730  *    Function Name : RecvCreateIC()
2731  *    Description   : create an IC for the connected client.
2732  *    Parameter     :
2733  *      req         : pointer to a request structure.
2734  *    Returned Value:
2735  *      = 0         : successed.
2736  *      > 0         : error, the number is error code.
2737  */
2738 static int
RecvCreateIC(req)2739 RecvCreateIC (req)
2740      XimRequestPacket *req;
2741 {
2742   CARD16 *buf_16 = (CARD16 *) req->data;
2743   XIMID im_id;
2744   XICID ic_id;
2745   int ret, len;
2746 
2747   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2748   if (!GetIMWithId (im_id))
2749     return XIM_BadProtocol;
2750 
2751   /* create IC. */
2752   len = (int) GET_CARD16 (buf_16[1]);
2753   ret = CreateClientIC (im_id, (CARD8 *) & buf_16[2], len, &ic_id);
2754   if (ret)
2755     return ret;
2756   cur_ic_id = ic_id;
2757 
2758   /* reply */
2759   ret = SendIdOnly (im_id, ic_id, XIM_CREATE_IC_REPLY, 0);
2760   if (ret)
2761     return ret;
2762 
2763   SendSetEventMask (im_id, ic_id);
2764   return 0;
2765 }
2766 
2767 /*
2768  *    Function Name : RecvSetICValues()
2769  *    Description   : set IC values to internal client context.
2770  *    Parameter     :
2771  *      req         : pointer to a request structure.
2772  *    Returned Value:
2773  *      = 0         : successed.
2774  *      > 0         : error, the number is error code.
2775  */
2776 static int
RecvSetICValues(req)2777 RecvSetICValues (req)
2778      XimRequestPacket *req;
2779 {
2780   CARD16 *buf_16 = (CARD16 *) req->data;
2781   XIMID im_id;
2782   XICID ic_id;
2783   int ret, n;
2784 
2785   XIMClientRec *xc;
2786 
2787   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2788   if (!GetIMWithId (im_id))
2789     return XIM_BadProtocol;
2790 
2791   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
2792   if (!(xc = GetICWithId (ic_id)))
2793     return XIM_BadProtocol;
2794 
2795   n = (int) GET_CARD16 (buf_16[2]);     /* 2 n byte length */
2796   ret = SetClientICValues ((CARD8 *) & buf_16[4], n, xc);
2797   if (ret)
2798     return ret;
2799 
2800   /* reply */
2801   return SendIdOnly (im_id, ic_id, XIM_SET_IC_VALUES_REPLY, 0);
2802 }
2803 
2804 /*
2805  *    Function Name : RecvGetICValues()
2806  *    Description   : encode IC values of client context, then send to client.
2807  *    Parameter     :
2808  *      req         : pointer to a request structure.
2809  *    Returned Value:
2810  *      = 0         : successed.
2811  *      > 0         : error, the number is error code.
2812  */
2813 static int
RecvGetICValues(req)2814 RecvGetICValues (req)
2815      XimRequestPacket *req;
2816 {
2817   CARD16 *buf_16 = (CARD16 *) req->data;
2818   CARD8 *reply;
2819   CARD8 value[BUFSIZ];
2820   XIMID im_id;
2821   XICID ic_id;
2822   int len, value_len, n;
2823   int ret;
2824 
2825   XIMClientRec *xc;
2826 
2827   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2828   if (!GetIMWithId (im_id))
2829     return XIM_BadProtocol;
2830 
2831   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
2832   if (!(xc = GetICWithId (ic_id)))
2833     return XIM_BadProtocol;
2834 
2835   n = GET_CARD16 (buf_16[2]);
2836   ret = EncodeICAttributes ((CARD8 *) & buf_16[3], n, xc, value, &value_len);
2837   if (ret)
2838     return ret;
2839 
2840   /* reply */
2841   len = sizeof (CARD16) +       /* 2 input-method-ID */
2842     sizeof (CARD16) +           /* 2 input-context-ID */
2843     sizeof (INT16) +            /* 2 byte length of ic-attr */
2844     sizeof (CARD16) +           /* 2 unused */
2845     value_len;                  /* n list of ic-attr */
2846 
2847   /* reply */
2848   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2849   len += AddHead (reply, XIM_GET_IC_VALUES_REPLY, 0, len);
2850   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2851   buf_16[0] = GET_CARD16 (im_id);
2852   buf_16[1] = GET_CARD16 (ic_id);
2853   buf_16[2] = GET_CARD16 (value_len);
2854   (void) memcpy ((char *) &buf_16[4], (char *) value, value_len);
2855   if (_WriteToClientFlush (reply, len) < 0)
2856     {
2857       FREE (reply);
2858       return XIM_BadSomething;
2859     }
2860   FREE (reply);
2861   return 0;
2862 }
2863 
2864 /*
2865  *    Function Name : JWMline_get()
2866  *    Description   : put preedit string into a common shared CT buffer which
2867  *                    can be accessed by GET_COMMON_CT_BUFFER, i.e., "ct_buf".
2868  *    Parameter     :
2869  *      base        : beginning position of preedit string.
2870  *      pre_len_returned
2871  *                  : returned length of the string got.
2872  *    Returned Value:
2873  *      <none>
2874  */
2875 static void
JWMline_get(base,pre_len_returned)2876 JWMline_get (base, pre_len_returned)
2877      int base;
2878      int *pre_len_returned;
2879 {
2880   register XIMLangRec *xl;
2881   register int wc_len, send_len;
2882   register wchar *JW_buf;
2883 
2884   *pre_len_returned = 0;
2885   xl = cur_p->cur_xl;
2886   JW_buf = xl->buf + base;
2887   send_len = wc_len = xl->max_pos - base;
2888   if (wc_len > 0)
2889     {
2890       while (1)
2891         {
2892           send_len = wchar_to_ct (cur_p->cur_xl->xlc, JW_buf, ct_buf, wc_len, ct_buf_max);
2893           if (send_len < -1)
2894             {
2895               return;
2896             }
2897           else if (send_len == -1)
2898             {
2899               if (realloc_ct_buf () < 0)
2900                 return;
2901             }
2902           else
2903             {
2904               break;
2905             }
2906         }
2907     }
2908   *pre_len_returned = ((send_len >= 0) ? send_len : 0);
2909 }
2910 
2911 /*
2912  *    Function Name : ResetClientIC()
2913  *    Description   : reset IC context of client.
2914  *    Parameter     :
2915  *      xc          : pointer to client structure.
2916  *      pre_str_filled
2917  *                  : returned preedit string.
2918  *                    The pre_str_filled parameter is only for readability,
2919  *                    it is used in a global variable "ct_buf".
2920  *      pre_len_returned
2921  *                  : length of preedit string
2922  *    Returned Value:
2923  *      = 0         : successed.
2924  *      > 0         : error, the number is error code.
2925  */
2926  /*ARGSUSED*/ static int
ResetClientIC(xc,pre_str_filled,pre_len_returned)2927 ResetClientIC (xc, pre_str_filled, pre_len_returned)
2928      XIMClientRec *xc;
2929      unsigned char *pre_str_filled;     /* only for readable ct_buf */
2930      int *pre_len_returned;
2931 {
2932   WnnClientRec *save_c_c;
2933   XIMClientRec *save_cur_p, *save_cur_x;
2934   int ret;
2935 
2936   /* refer to util.c: ResetIC() */
2937   {
2938     save_c_c = c_c;
2939     save_cur_p = cur_p;
2940     save_cur_x = cur_x;
2941     cur_x = xc;
2942     if (IsPreeditNothing (xc))
2943       {
2944         cur_p = xc->root_pointer->ximclient;
2945       }
2946     else
2947       {
2948         cur_p = cur_x;
2949       }
2950     c_c = cur_p->cur_xl->w_c;
2951     ret = reset_c_b ();
2952     JWMline_get (0, pre_len_returned);
2953     JWMline_clear (0);
2954     c_c = save_c_c;
2955     cur_p = save_cur_p;
2956     cur_x = save_cur_x;
2957     if (ret == -1)
2958       return XIM_BadProtocol;
2959   }
2960   return 0;
2961 }
2962 
2963 /*
2964  *    Function Name : RecvResetIC()
2965  *    Description   : reset IC context as client asks.
2966  *    Parameter     :
2967  *      req         : pointer to a request structure.
2968  *    Returned Value:
2969  *      = 0         : successed.
2970  *      > 0         : error, the number is error code.
2971  */
2972 static int
RecvResetIC(req)2973 RecvResetIC (req)
2974      XimRequestPacket *req;
2975 {
2976   CARD16 *buf_16 = (CARD16 *) req->data;
2977   CARD8 *reply;
2978   XIMID im_id;
2979   XICID ic_id;
2980   int len, pre_len;
2981   int ret;
2982   unsigned char *pre_str;
2983 
2984   XIMClientRec *xc;
2985 
2986   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
2987   if (!GetIMWithId (im_id))
2988     return XIM_BadProtocol;
2989 
2990   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
2991   if (!(xc = GetICWithId (ic_id)))
2992     return XIM_BadProtocol;
2993 
2994   pre_str = GET_SHARED_CT_BUFFER ();
2995   ret = ResetClientIC (xc, pre_str, &pre_len);
2996   if (ret)
2997     return ret;
2998 
2999   /* reply */
3000   len = sizeof (CARD16) +       /* 2 input-method-ID */
3001     sizeof (CARD16) +           /* 2 input-context-ID */
3002     sizeof (INT16) +            /* 2 byte length of string */
3003     pre_len +                   /* n LISTofBYTE */
3004     PAD (sizeof (INT16) + pre_len);     /* p Pad(2 + n) */
3005 
3006   /* reply */
3007   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3008   len += AddHead (reply, XIM_RESET_IC_REPLY, 0, len);
3009   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3010   buf_16[0] = GET_CARD16 (im_id);
3011   buf_16[1] = GET_CARD16 (ic_id);
3012   buf_16[2] = GET_CARD16 (pre_len);
3013   if (pre_len > 0)
3014     (void) memcpy ((char *) &buf_16[3], (char *) pre_str, pre_len);
3015 
3016   if (_WriteToClientFlush (reply, len) < 0)
3017     {
3018       FREE (reply);
3019       return XIM_BadSomething;
3020     }
3021   FREE (reply);
3022   return 0;
3023 }
3024 
3025 /*
3026  *    Function Name : RecvDestroyIC()
3027  *    Description   : destroy an IC context.
3028  *    Parameter     :
3029  *      req         : pointer to a request structure.
3030  *    Returned Value:
3031  *      = 0         : successed.
3032  *      > 0         : error, the number is error code.
3033  */
3034 static int
RecvDestroyIC(req)3035 RecvDestroyIC (req)
3036      XimRequestPacket *req;
3037 {
3038   CARD16 *buf_16 = (CARD16 *) req->data;
3039   XIMID im_id;
3040   XICID ic_id;
3041 
3042   XIMClientRec *xc;
3043 
3044   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3045   if (!GetIMWithId (im_id))
3046     return XIM_BadProtocol;
3047 
3048   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
3049   if (!(xc = GetICWithId (ic_id)))
3050     return XIM_BadProtocol;
3051   (void) destroy_client (xc);
3052   cur_ic_id = 0;
3053 
3054   /* reply */
3055   return SendIdOnly (im_id, ic_id, XIM_DESTROY_IC_REPLY, 0);
3056 }
3057 
3058 /*
3059  *    Function Name : SetClientICFocus()
3060  *    Description   : set IC focus to the specified client.
3061  *    Parameter     :
3062  *      xc          : pointer to client structure.
3063  *    Returned Value:
3064  *      = 0         : successed.
3065  *      > 0         : error, the number is error code.
3066  */
3067 static int
SetClientICFocus(xc)3068 SetClientICFocus (xc)
3069      XIMClientRec *xc;
3070 {
3071   register XIMInputRec *xi;
3072   XIMClientRec *save_cur_p, *save_cur_x;
3073   WnnClientRec *save_c_c;
3074 
3075   /* modified from util.c: SetICFocus() */
3076   {
3077     for (xi = input_list; xi != NULL; xi = xi->next)
3078       {
3079         if (xi->w == xc->focus_window)
3080           break;
3081       }
3082     if (xi == NULL)
3083       {
3084         if (!(xi = (XIMInputRec *) Malloc (sizeof (XIMInputRec))))
3085           {
3086             malloc_error ("allocation of Focus data struct");
3087             return XIM_BadAlloc;
3088           }
3089         xi->w = xc->focus_window;
3090         xi->pclient = xc;
3091         xi->next = NULL;
3092         add_inputlist (xi);
3093       }
3094     save_cur_p = cur_p;
3095     save_cur_x = cur_x;
3096     save_c_c = c_c;
3097     cur_x = xc;
3098     if (IsPreeditNothing (xc))
3099       {
3100         cur_p = xc->root_pointer->ximclient;
3101       }
3102     else
3103       {
3104         cur_p = cur_x;
3105       }
3106     c_c = cur_p->cur_xl->w_c;
3107     cur_rk = c_c->rk;
3108     cur_rk_table = cur_rk->rk_table;
3109 #ifdef  CALLBACKS
3110     if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsStatusCallbacks (xc))
3111       {
3112 #else /* CALLBACKS */
3113     if (IsPreeditPosition (xc) || IsPreeditArea (xc))
3114       {
3115 #endif /* CALLBACKS */
3116         reset_preedit (xc);
3117       }
3118 #ifdef  CALLBACKS
3119     if (IsStatusArea (xc) || IsStatusCallbacks (xc))
3120       {
3121 #else /* CALLBACKS */
3122     if (IsStatusArea (xc))
3123       {
3124 #endif /* CALLBACKS */
3125         visual_status ();
3126       }
3127     cur_p = save_cur_p;
3128     cur_x = save_cur_x;
3129     c_c = save_c_c;
3130     if (c_c)
3131       {
3132         cur_rk = c_c->rk;
3133         cur_rk_table = cur_rk->rk_table;
3134       }
3135   }
3136   return 0;
3137 }
3138 
3139 /*
3140  *    Function Name : UnsetClientICFocus()
3141  *    Description   : unset IC focus to the specified client.
3142  *    Parameter     :
3143  *      xc          : pointer to client structure.
3144  *    Returned Value:
3145  *      = 0         : successed.
3146  *      > 0         : error, the number is error code.
3147  */
3148 static int
UnsetClientICFocus(xc)3149 UnsetClientICFocus (xc)
3150      XIMClientRec *xc;
3151 {
3152   register XIMInputRec *xi;
3153   XIMClientRec *save_cur_p, *save_cur_x;
3154   WnnClientRec *save_c_c;
3155 
3156   /* modified from util.c: UnsetICFocus() */
3157   {
3158     for (xi = input_list; xi != NULL; xi = xi->next)
3159       {
3160         if (xi->w == xc->focus_window)
3161           break;
3162       }
3163     if (xi == NULL)
3164       {
3165         return XIM_BadFocusWindow;
3166       }
3167     else
3168       {
3169         remove_inputlist (xi);
3170         if (cur_input == xi)
3171           cur_input = 0;
3172         Free ((char *) xi);
3173         save_cur_p = cur_p;
3174         save_cur_x = cur_x;
3175         save_c_c = c_c;
3176         cur_x = xc;
3177         if (IsPreeditNothing (xc))
3178           {
3179             cur_p = xc->root_pointer->ximclient;
3180           }
3181         else
3182           {
3183             cur_p = cur_x;
3184           }
3185         c_c = cur_p->cur_xl->w_c;
3186         cur_rk = c_c->rk;
3187         cur_rk_table = cur_rk->rk_table;
3188 #ifdef  CALLBACKS
3189         if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsPreeditCallbacks (xc))
3190           {
3191 #else /* CALLBACKS */
3192         if (IsPreeditPosition (xc) || IsPreeditArea (xc))
3193           {
3194 #endif /* CALLBACKS */
3195             invisual_window ();
3196           }
3197 #ifdef  CALLBACKS
3198         if (IsStatusArea (xc) || IsStatusCallbacks (xc))
3199           {
3200 #else /* CALLBACKS */
3201         if (IsStatusArea (xc))
3202           {
3203 #endif /* CALLBACKS */
3204             invisual_status ();
3205           }
3206         cur_p = save_cur_p;
3207         cur_x = save_cur_x;
3208         c_c = save_c_c;
3209         if (c_c)
3210           {
3211             cur_rk = c_c->rk;
3212             cur_rk_table = cur_rk->rk_table;
3213           }
3214       }
3215   }
3216   return 0;
3217 }
3218 
3219 /*
3220  *    Function Name : RecvSetICFocus()
3221  *    Description   : set IC focus.
3222  *    Parameter     :
3223  *      req         : pointer to a request structure.
3224  *    Returned Value:
3225  *      = 0         : successed.
3226  *      > 0         : error, the number is error code.
3227  */
3228 static int
RecvSetICFocus(req)3229 RecvSetICFocus (req)
3230      XimRequestPacket *req;
3231 {
3232   CARD16 *buf_16 = (CARD16 *) req->data;
3233   XIMID im_id;
3234   XICID ic_id;
3235 
3236   XIMClientRec *xc;
3237 
3238   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3239   if (!GetIMWithId (im_id))
3240     return XIM_BadProtocol;
3241 
3242   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
3243   if (!(xc = GetICWithId (ic_id)))
3244     return XIM_BadProtocol;
3245 
3246   return SetClientICFocus (xc);
3247 
3248   /* asynchoronous request, no reply */
3249 }
3250 
3251 /*
3252  *    Function Name : RecvUnsetICFocus()
3253  *    Description   : unset IC focus.
3254  *    Parameter     :
3255  *      req         : pointer to a request structure.
3256  *    Returned Value:
3257  *      = 0         : successed.
3258  *      > 0         : error, the number is error code.
3259  */
3260 static int
RecvUnsetICFocus(req)3261 RecvUnsetICFocus (req)
3262      XimRequestPacket *req;
3263 {
3264   CARD16 *buf_16 = (CARD16 *) req->data;
3265   XIMID im_id;
3266   XICID ic_id;
3267 
3268   XIMClientRec *xc;
3269 
3270   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3271   if (!GetIMWithId (im_id))
3272     return XIM_BadProtocol;
3273 
3274   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
3275   if (!(xc = GetICWithId (ic_id)))
3276     return XIM_BadProtocol;
3277 
3278   return UnsetClientICFocus (xc);
3279 
3280   /* asynchoronous request, no reply */
3281 }
3282 
3283 /*
3284  *    Function Name : RecvGetIMValues()
3285  *    Description   : encode IM values to byte data, then send it to client.
3286  *    Parameter     :
3287  *      req         : pointer to a request structure.
3288  *    Returned Value:
3289  *      = 0         : successed.
3290  *      > 0         : error, the number is error code.
3291  */
3292 static int
RecvGetIMValues(req)3293 RecvGetIMValues (req)
3294      XimRequestPacket *req;
3295 {
3296   CARD16 *buf_16 = (CARD16 *) req->data;
3297   CARD8 *reply;
3298   XIMID im_id;
3299   CARD8 value[BUFSIZ];
3300   int len, value_len, n;
3301   int ret;
3302   XIMContextRec *im;
3303 
3304   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3305   if (!(im = GetIMWithId (im_id)))
3306     return XIM_BadProtocol;
3307 
3308   n = GET_CARD16 (buf_16[1]);
3309   ret = EncodeIMAttributes ((CARD8 *) & buf_16[2], n, im, value, &value_len);
3310   if (ret)
3311     return ret;
3312 
3313   /* reply */
3314   len = sizeof (CARD16) +       /* 2 input-method-ID */
3315     sizeof (INT16) +            /* 2 byte length of im-attr */
3316     value_len;                  /* n list of im-attr */
3317 
3318   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3319   len += AddHead (reply, XIM_GET_IM_VALUES_REPLY, 0, len);
3320   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3321   buf_16[0] = GET_CARD16 (im_id);
3322   buf_16[1] = GET_CARD16 (value_len);
3323   (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
3324   if (_WriteToClientFlush (reply, len) < 0)
3325     {
3326       FREE (reply);
3327       return XIM_BadSomething;
3328     }
3329   FREE (reply);
3330   return 0;
3331 }
3332 
3333 /*
3334  *    Function Name : RecvSetIMValues()
3335  *    Description   : decode IM values, then send it to client context.
3336  *    Parameter     :
3337  *      req         : pointer to a request structure.
3338  *    Returned Value:
3339  *      = 0         : successed.
3340  *      > 0         : error, the number is error code.
3341  */
3342 static int
RecvSetIMValues(req)3343 RecvSetIMValues (req)
3344      XimRequestPacket *req;
3345 {
3346   CARD16 *buf_16 = (CARD16 *) req->data;
3347   CARD8 *reply;
3348   XIMID im_id;
3349   int len, n;
3350   int ret;
3351   XIMContextRec *im;
3352 
3353   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3354   if (!(im = GetIMWithId (im_id)))
3355     return XIM_BadProtocol;
3356 
3357   n = (int) GET_CARD16 (buf_16[1]);     /* 2 n byte length */
3358   ret = SetClientIMValues ((CARD8 *) & buf_16[2], n, im);
3359   if (ret)
3360     return ret;
3361 
3362   /* reply */
3363   len = sizeof (CARD16) +       /* 2 input-method-ID */
3364     sizeof (CARD16);            /* 2 unused */
3365   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3366   len += AddHead (reply, XIM_SET_IM_VALUES_REPLY, 0, len);
3367   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3368   buf_16[0] = GET_CARD16 (im_id);
3369   if (_WriteToClientFlush (reply, len) < 0)
3370     {
3371       FREE (reply);
3372       return XIM_BadSomething;
3373     }
3374   FREE (reply);
3375   return 0;
3376 }
3377 
3378 /*
3379  *    Function Name : SendCommit()
3380  *    Description   : commit a string to client, the string is converted
3381  *                    by input method, such kanji, and is encoded in CT.
3382  *    Parameter     :
3383  *      im_id       : client input-method-id.
3384  *      ic_id       : client input-context-id.
3385  *      flag        : flag of XimLookupKeySym, XimLookupChars or both.
3386  *      keysym      : keysym if committed.
3387  *      ct_str      : CT string if committed.
3388  *      ct_len      : length of string.
3389  *    Returned Value:
3390  *      = 0         : successed.
3391  *      > 0         : error, the number is error code.
3392  */
3393 static int
SendCommit(im_id,ic_id,flag,keysym,ct_str,ct_len)3394 SendCommit (im_id, ic_id, flag, keysym, ct_str, ct_len)
3395      XIMID im_id;
3396      XICID ic_id;
3397      int flag;
3398      KeySym keysym;
3399      char *ct_str;
3400      int ct_len;
3401 {
3402   CARD16 *buf_16;
3403   CARD32 *buf_32;
3404   CARD8 *reply;
3405   int len;
3406 
3407   XIMClientRec *xc;
3408 
3409   if (!(xc = GetICWithId (ic_id)) || xc->im_id != im_id)
3410     return XIM_BadProtocol;
3411 
3412   flag |= XimSYNCHRONUS;        /* ask sync */
3413 
3414   /* send */
3415   len = sizeof (CARD16) +       /* 2 input-method-id */
3416     sizeof (CARD16) +           /* 2 input-context-id */
3417     sizeof (BITMASK16) +        /* 2 flag */
3418     LENGTH_KEYSYM (flag, sizeof (CARD32)) +     /* 2+6 KeySym */
3419     LENGTH_STRING_WITH_FLAG (flag, ct_len);     /* 2+n+Pad(2+n) string */
3420 
3421   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3422   len += AddHead (reply, XIM_COMMIT, 0, len);
3423   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3424   buf_16[0] = GET_CARD16 (im_id);
3425   buf_16[1] = GET_CARD16 (ic_id);
3426   buf_16[2] = GET_CARD16 (flag);
3427   buf_16 = (CARD16 *) & buf_16[3];
3428   if (flag & XimLookupKeySym)
3429     {
3430       buf_32 = (CARD32 *) & buf_16[1];
3431       buf_32[0] = GET_CARD32 (keysym);
3432       buf_16 = (CARD16 *) & buf_32[1];
3433     }
3434   if (flag & XimLookupChars)
3435     {
3436       buf_16[0] = GET_CARD16 (ct_len);
3437       (void) memcpy ((char *) &buf_16[1], ct_str, ct_len);
3438     }
3439   if (_WriteToClientFlush (reply, len) < 0)
3440     {
3441       FREE (reply);
3442       return XIM_BadSomething;
3443     }
3444   FREE (reply);
3445 
3446   if (ClientSyncDone (xc) == True)
3447     return SendSyncReply (im_id, ic_id);
3448   else
3449     return 0;
3450 }
3451 
3452 /*
3453  *    Function Name : SendForwardEvent()
3454  *    Description   : usually it is to send event back to client, e.g.
3455  *                    when no filter in server.
3456  *    Parameter     :
3457  *      im_id       : client input-method-id.
3458  *      ic_id       : client input-context-id.
3459  *      serial      : serial number of event.
3460  *      event       : pointer to XEvent.
3461  *    Returned Value:
3462  *      = 0         : successed.
3463  *      > 0         : error, the number is error code.
3464  */
3465 static int
SendForwardEvent(im_id,ic_id,serial,event)3466 SendForwardEvent (im_id, ic_id, serial, event)
3467      XIMID im_id;
3468      XICID ic_id;
3469      int serial;
3470      XEvent *event;
3471 {
3472   CARD16 *buf_16;
3473   CARD8 *reply;
3474   int len;
3475   int flag;
3476 
3477   /* send */
3478   len = sizeof (CARD16) +       /* 2 input-method-ID */
3479     sizeof (CARD16) +           /* 2 input-context-ID */
3480     sizeof (BITMASK16) +        /* 2 flag */
3481     sizeof (CARD16) +           /* 2 serial number */
3482     sizeof (xEvent);            /* n XEVENT */
3483 
3484   flag = 0;                     /* no sync flag */
3485   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3486   len += AddHead (reply, XIM_FORWARD_EVENT, 0, len);
3487   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3488   buf_16[0] = GET_CARD16 (im_id);
3489   buf_16[1] = GET_CARD16 (ic_id);
3490   buf_16[2] = GET_CARD16 (flag);
3491   buf_16[3] = GET_CARD16 (serial);
3492   if (_XimEventToWire (event, (xEvent *) & buf_16[4]) == False)
3493     return XIM_BadSomething;
3494   if (_WriteToClientFlush (reply, len) < 0)
3495     {
3496       FREE (reply);
3497       return XIM_BadSomething;
3498     }
3499   FREE (reply);
3500   return 0;
3501 }
3502 
3503 /*
3504  *    Function Name : ExecInputMethod()
3505  *    Description   : execute input method to do some henkan (conversion).
3506  *                    This is referred to keyin.c: RequestDispatch() on
3507  *                    the case of XIM_Event.
3508  *    Parameter     :
3509  *      im_id       : client input-method-id.
3510  *      ic_id       : client input-context-id.
3511  *      xevp        : pointer to event.
3512  *    Returned Value:
3513  *      = 0         : successed.
3514  *      > 0         : error, the number is error code.
3515  */
3516 static int
ExecInputMethod(im_id,ic_id,xevp)3517 ExecInputMethod (im_id, ic_id, xevp)
3518      XIMID im_id;
3519      XICID ic_id;
3520      XEvent *xevp;
3521 {
3522   int buff[32], in;
3523   int ret;
3524   register int i, n_bytes;
3525 
3526   ret = key_input (buff, xevp);
3527   if (ret == 0)
3528     {
3529       /* send_nofilter() */
3530       return xim_send_nofilter ();
3531     }
3532   else if (ret > 0)
3533     {
3534       for (i = 0; i < ret;)
3535         {
3536           n_bytes = get_cswidth_by_char (in = buff[i++]);
3537           for (; n_bytes > 1 && i < ret; n_bytes--, i++)
3538             {
3539               in = (in << 8) + buff[i];
3540             }
3541           in_put (in);
3542         }
3543     }
3544   return 0;
3545 }
3546 
3547 /*
3548  *    Function Name : RecvForwardEvent()
3549  *    Description   : filter event forwarded by client to execute input
3550  *                    method.
3551  *    Parameter     :
3552  *      req         : pointer to a request structure.
3553  *    Returned Value:
3554  *      = 0         : successed.
3555  *      > 0         : error, the number is error code.
3556  */
3557 static int
RecvForwardEvent(req)3558 RecvForwardEvent (req)
3559      XimRequestPacket *req;
3560 {
3561   CARD16 *buf_16 = (CARD16 *) req->data;
3562   XIMID im_id;
3563   XICID ic_id;
3564   int ret;
3565   int flag, serial;
3566   XEvent event;
3567 
3568   XIMClientRec *xc;
3569 
3570   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3571   if (!GetIMWithId (im_id))
3572     return XIM_BadProtocol;
3573 
3574   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
3575   if (!(xc = GetICWithId (ic_id)))
3576     return XIM_BadProtocol;
3577 
3578   flag = (int) GET_CARD16 (buf_16[2]);
3579   serial = (int) GET_CARD16 (buf_16[3]);
3580 
3581   SetClientSync (xc, True);
3582 
3583   if (_XimWireToEvent (dpy, serial, (xEvent *) & buf_16[4], &event) == False)
3584     return XIM_BadProtocol;
3585   /*
3586    * save event which will back to client if no filter.
3587    */
3588   (void) memcpy ((char *) &(xc->cur_event), (char *) &event, sizeof (XEvent));
3589 
3590   ret = ExecInputMethod (im_id, ic_id, &event);
3591   /*
3592    * if it is async (no XimSYNCHRONUS), force 0 returned, so no anything
3593    * even no error is sent to client.
3594    */
3595   if (ret)
3596     return ((flag & XimSYNCHRONUS) ? ret : 0);
3597 
3598   if (ClientSyncDone (xc) == True)
3599     return SendSyncReply (im_id, ic_id);
3600   else
3601     return 0;
3602 }
3603 
3604 /*
3605  *    Function Name : RecvStrConversionReply()
3606  *    Description   : send a request that is the format of:
3607  *    Parameter     :
3608  *      req         : pointer to a request structure.
3609  *    Returned Value:
3610  *      = 0         : successed.
3611  *      > 0         : error, the number is error code.
3612  */
3613 static int
RecvStrConversionReply(req)3614 RecvStrConversionReply (req)
3615      XimRequestPacket *req;
3616 {
3617   /* don't care in this model. */
3618   return 0;
3619 }
3620 
3621 #ifdef CALLBACKS
3622 
3623 /*
3624  *    Function Name : CopyText()
3625  *    Description   : copy string and feedback array to byte data
3626  *    Parameter     :
3627  *      bur         : pointer to the byte data.
3628  *      str         : string
3629  *      feedback    : array of feedback.
3630  *      feedback_num: number of feedback.
3631  *    Returned Value:
3632  *      <none>
3633  */
3634 static void
CopyText(buf,str,str_len,feedback,feedback_num)3635 CopyText (buf, str, str_len, feedback, feedback_num)
3636      CARD8 *buf;
3637      char *str;
3638      int str_len;
3639      XIMFeedback *feedback;
3640      int feedback_num;
3641 {
3642   CARD16 *buf_16;
3643   CARD32 *buf_32;
3644   CARD32 *save_32;
3645   BITMASK32 status = 0;
3646   int i;
3647 
3648   save_32 = (CARD32 *) buf;
3649   buf_16 = (CARD16 *) & save_32[1];
3650   if (str_len > 0)
3651     {
3652       buf_16[0] = GET_CARD16 (str_len);
3653       (void) strncpy ((char *) &buf_16[1], str, str_len);
3654       buf_16 = (CARD16 *) ((CARD8 *) buf_16 + sizeof (CARD16) + PAD (sizeof (CARD16) + str_len));
3655     }
3656   else
3657     {
3658       status |= XIMNoString;
3659     }
3660   if (feedback_num > 0)
3661     {
3662       buf_16[0] = GET_CARD16 (feedback_num);
3663       buf_32 = (CARD32 *) & buf_16[2];
3664       for (i = 0; i < feedback_num; i++)
3665         {
3666           buf_32[i] = GET_CARD32 (feedback[i]);
3667         }
3668     }
3669   else
3670     {
3671       status |= XIMNoFeedback;
3672     }
3673   save_32[0] = GET_CARD32 (status);
3674 }
3675 
3676 /*
3677  *    Function Name : SendPreeditDraw()
3678  *    Description   : send the request of XIM_PREEDT_DRAW.
3679  *    Parameter     :
3680  *      im_id       : client input-method-id.
3681  *      ic_id       : client input-context-id.
3682  *      caret       : caret
3683  *      chg_first   : first of change.
3684  *      chg_len     : length of change.
3685  *      str         : string.
3686  *      str_len     : length of string.
3687  *      feedback    : array of feedback.
3688  *      feedback_num: number of feedback.
3689  *    Returned Value:
3690  *      = 0         : successed.
3691  *      > 0         : error, the number is error code.
3692  */
3693 static int
SendPreeditDraw(im_id,ic_id,caret,chg_first,chg_len,str,str_len,feedback,feedback_num)3694 SendPreeditDraw (im_id, ic_id, caret, chg_first, chg_len, str, str_len, feedback, feedback_num)
3695      XIMID im_id;
3696      XICID ic_id;
3697      INT32 caret;
3698      INT32 chg_first;
3699      INT32 chg_len;
3700      char *str;
3701      int str_len;
3702      XIMFeedback *feedback;
3703      int feedback_num;
3704 {
3705   CARD8 *reply;
3706   CARD16 *buf_16;
3707   CARD32 *buf_32;
3708   int len;
3709 
3710   /* send */
3711   len = sizeof (CARD16) +       /* 2 input-method-ID */
3712     sizeof (CARD16) +           /* 2 input-context-ID */
3713     sizeof (INT32) +            /* 4 caret */
3714     sizeof (INT32) +            /* 4 chg_first */
3715     sizeof (INT32) +            /* 4 chg_length */
3716     sizeof (BITMASK32) +        /* 4 status */
3717     LENGTH_STRING (str_len) +   /* x string */
3718     LENGTH_FEEDBACK (feedback_num);     /* x feedback array */
3719 
3720   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3721   len += AddHead (reply, XIM_PREEDIT_DRAW, 0, len);
3722   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3723   buf_16[0] = GET_CARD16 (im_id);
3724   buf_16[1] = GET_CARD16 (ic_id);
3725   buf_32 = (CARD32 *) & buf_16[2];
3726   buf_32[0] = GET_CARD32 (caret);
3727   buf_32[1] = GET_CARD32 (chg_first);
3728   buf_32[2] = GET_CARD32 (chg_len);
3729   buf_16 = (CARD16 *) & buf_32[3];
3730   CopyText ((CARD8 *) & buf_32[3], str, str_len, feedback, feedback_num);
3731   if (_WriteToClientFlush (reply, len) < 0)
3732     {
3733       FREE (reply);
3734       return XIM_BadSomething;
3735     }
3736   FREE (reply);
3737   return 0;
3738 }
3739 
3740 /*
3741  *    Function Name : SendPreeditCaret()
3742  *    Description   : send the request of XIM_PREEDIT_CARET.
3743  *    Parameter     :
3744  *      im_id       : client input-method-id.
3745  *      ic_id       : client input-context-id.
3746  *      pos         : position
3747  *      direct      : direction of caret.
3748  *      style       : style of caret.
3749  *    Returned Value:
3750  *      = 0         : successed.
3751  *      > 0         : error, the number is error code.
3752  */
3753 static int
SendPreeditCaret(im_id,ic_id,pos,direct,style)3754 SendPreeditCaret (im_id, ic_id, pos, direct, style)
3755      XIMID im_id;
3756      XICID ic_id;
3757      INT32 pos;
3758      CARD32 direct;
3759      CARD32 style;
3760 {
3761   CARD8 *reply;
3762   CARD16 *buf_16;
3763   CARD32 *buf_32;
3764   int len;
3765 
3766   /* send */
3767   len = sizeof (CARD16) +       /* 2 input-method-ID */
3768     sizeof (CARD16) +           /* 2 input-context-ID */
3769     sizeof (INT32) +            /* 4 position */
3770     sizeof (CARD32) +           /* 4 direction */
3771     sizeof (CARD32);            /* 4 style */
3772 
3773   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3774   len += AddHead (reply, XIM_PREEDIT_CARET, 0, len);
3775   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3776   buf_16[0] = GET_CARD16 (im_id);
3777   buf_16[1] = GET_CARD16 (ic_id);
3778   buf_32 = (CARD32 *) & buf_16[2];
3779   buf_32[0] = GET_CARD32 (pos);
3780   buf_32[1] = GET_CARD32 (direct);
3781   buf_32[2] = GET_CARD32 (style);
3782   if (_WriteToClientFlush (reply, len) < 0)
3783     {
3784       FREE (reply);
3785       return XIM_BadSomething;
3786     }
3787   FREE (reply);
3788   return 0;
3789 }
3790 
3791 /*
3792  *    Function Name : SendStatusDraw()
3793  *    Description   : send the request of XIM_STATUS_DRAW.
3794  *    Parameter     :
3795  *      im_id       : client input-method-id.
3796  *      ic_id       : client input-context-id.
3797  *      st_type     : type of status.
3798  *      str         : string.
3799  *      str_len     : length of string.
3800  *      feedback    : array of feedback.
3801  *      feedback_num: number of feedback.
3802  *      pixmap      : pixmap data.
3803  *    Returned Value:
3804  *      = 0         : successed.
3805  *      > 0         : error, the number is error code.
3806  */
3807 static int
SendStatusDraw(im_id,ic_id,st_type,str,str_len,feedback,feedback_num,pixmap)3808 SendStatusDraw (im_id, ic_id, st_type, str, str_len, feedback, feedback_num, pixmap)
3809      XIMID im_id;
3810      XICID ic_id;
3811      CARD32 st_type;
3812      char *str;
3813      int str_len;
3814      XIMFeedback *feedback;
3815      int feedback_num;
3816      PIXMAP pixmap;
3817 {
3818   CARD8 *reply;
3819   CARD16 *buf_16;
3820   CARD32 *buf_32;
3821   int len;
3822 
3823   /* send */
3824   len = sizeof (CARD16) +       /* 2 input-method-ID */
3825     sizeof (CARD16) +           /* 2 input-context-ID */
3826     sizeof (CARD32) +           /* 4 type */
3827     sizeof (BITMASK32) +        /* 4 status */
3828     LENGTH_TEXT (st_type, str_len, feedback_num) +      /* text */
3829     LENGTH_PIXMAP (st_type);    /* x pixmap */
3830 
3831   reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3832   len += AddHead (reply, XIM_STATUS_DRAW, 0, len);
3833   buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3834   buf_16[0] = GET_CARD16 (im_id);
3835   buf_16[1] = GET_CARD16 (ic_id);
3836   buf_32 = (CARD32 *) & buf_16[2];
3837   buf_32[0] = GET_CARD32 (st_type);
3838   if (st_type == XIMTextType)
3839     {
3840       CopyText ((CARD8 *) & buf_32[1], str, str_len, feedback, feedback_num);
3841     }
3842   else
3843     {
3844       buf_32[1] = GET_CARD32 (pixmap);
3845     }
3846   if (_WriteToClientFlush (reply, len) < 0)
3847     {
3848       FREE (reply);
3849       return XIM_BadSomething;
3850     }
3851   FREE (reply);
3852   return 0;
3853 }
3854 
3855 /*
3856  *    Function Name : RecvPreeditStartReply()
3857  *    Description   : receive a reply from client.
3858  *    Parameter     :
3859  *      req         : pointer to a request structure.
3860  *    Returned Value:
3861  *      = 0         : successed.
3862  *      > 0         : error, the number is error code.
3863  */
3864 static int
RecvPreeditStartReply(req)3865 RecvPreeditStartReply (req)
3866      XimRequestPacket *req;
3867 {
3868   /* don't care. */
3869   return 0;
3870 }
3871 
3872 /*
3873  *    Function Name : RecvPreeditCaretReply()
3874  *    Description   : receive a reply from client.
3875  *    Parameter     :
3876  *      req         : pointer to a request structure.
3877  *    Returned Value:
3878  *      = 0         : successed.
3879  *      > 0         : error, the number is error code.
3880  */
3881 static int
RecvPreeditCaretReply(req)3882 RecvPreeditCaretReply (req)
3883      XimRequestPacket *req;
3884 {
3885   /* don't care. */
3886   return 0;
3887 }
3888 
3889 #endif /* CALLBACKS */
3890 
3891 #if defined(EXT_MOVE) || defined(SPOT)
3892 
3893 /*
3894  *    Function Name : RecvExtMove()
3895  *    Description   : change only the point of spot.
3896  *    Parameter     :
3897  *      req         : pointer to a request structure.
3898  *    Returned Value:
3899  *      <none>
3900  */
3901 static int
RecvExtMove(req)3902 RecvExtMove (req)
3903      XimRequestPacket *req;
3904 {
3905   CARD16 *buf_16 = (CARD16 *) req->data;
3906   XIMID im_id;
3907   XICID ic_id;
3908   short x, y;
3909   XIMClientRec *xc;
3910 
3911   im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]);   /* 2 input-method-ID */
3912   if (!GetIMWithId (im_id))
3913     return XIM_BadProtocol;
3914 
3915   ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]);   /* 2 input-context-ID */
3916   if (!(xc = GetICWithId (ic_id)))
3917     return XIM_BadProtocol;
3918 
3919   x = (short) GET_CARD16 (buf_16[2]);
3920   y = (short) GET_CARD16 (buf_16[3]);
3921   if (change_spotlocation (xc, x, y) != 0)
3922     return XIM_BadSpotLocation;
3923   else
3924     return 0;
3925 
3926   /* asynchoronous request, no reply */
3927 }
3928 
3929 #endif /* defined(EXT_MOVE) || defined(SPOT) */
3930 
3931 /*
3932  *    Function Name : AppendServerToProperty()
3933  *    Description   : append server id to IM_SERVERS property.
3934  *                    Don't use PropModeAppend that will propagate a same
3935  *                    server id more and more in the property.
3936  *    Parameter     :
3937  *      disp        : pointer to X display.
3938  *      win         : window that holds the property.
3939  *      imserver    : our server id to be appended.
3940  *    Returned Value:
3941  *      True        : success.
3942  *      False       : error.
3943  */
3944 static Bool
AppendServerToProperty(disp,win,imserver)3945 AppendServerToProperty (disp, win, imserver)
3946      Display *disp;
3947      Window win;
3948      Atom imserver;
3949 {
3950   Atom server_atom, actual_type;
3951   Atom *atom_list, *new_list;
3952   int actual_format;
3953   unsigned long nitems, bytes_after;
3954   unsigned char *prop_return;
3955   int i;
3956 
3957   server_atom = XInternAtom (disp, XIM_SERVERS, False);
3958   (void) XGetWindowProperty (disp, win, server_atom, 0L, 1000000L, False, XA_ATOM, &actual_type, &actual_format, &nitems, &bytes_after, &prop_return);
3959 
3960   if (nitems > 0 && (actual_type != XA_ATOM || actual_format != 32))
3961     {
3962       return False;
3963     }
3964   if (nitems > 0)
3965     {
3966       /*
3967        * search whether our server id has been registered or not.
3968        */
3969       atom_list = (Atom *) prop_return;
3970       for (i = 0; i < nitems; i++)
3971         {
3972           if (atom_list[i] == imserver)
3973             return True;
3974         }
3975       new_list = (Atom *) Malloc ((nitems + 1) * sizeof (Atom));
3976       if (!new_list)
3977         {
3978           malloc_error ("no memory for atom list.");
3979           return False;
3980         }
3981       (void) memcpy ((char *) new_list, (char *) prop_return, nitems * sizeof (Atom));
3982       new_list[nitems] = imserver;
3983     }
3984   else
3985     {
3986       new_list = &imserver;
3987     }
3988 
3989   /*
3990    * append our server id to IM_SERVERS property.
3991    */
3992   XChangeProperty (disp, win, server_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *) new_list, (nitems + 1));
3993   if (nitems > 0)
3994     {
3995       XFree ((char *) prop_return);
3996       XFree ((char *) new_list);
3997     }
3998   return True;
3999 }
4000 
4001 /*--------------------------------------------------------------------*
4002  *                                                                    *
4003  *                         Public Functions                           *
4004  *                                                                    *
4005  *--------------------------------------------------------------------*/
4006 
4007 /*
4008  *    Function Name : XimError()
4009  *    Description   : take the breakpoint of error when it occurs at any time.
4010  *    Parameter     :
4011  *      fd          : socket id of IM client.
4012  *    Returned Value:
4013  *      <none>
4014  */
4015 #if NeedFunctionPrototypes
4016 void
XimError(int fd)4017 XimError (int fd)
4018 #else
4019 void
4020 XimError (fd)
4021      int fd;
4022 #endif /* NeedFunctionPrototypes */
4023 {
4024   register XIMClientRec *xc;
4025 
4026   for (xc = ximclient_list; xc != NULL; xc = xc->next)
4027     {
4028       if (xc->fd == fd)
4029         {
4030           (void) RemoveIMWithId ((XIMID) xc->im_id);
4031         }
4032     }
4033 }
4034 
4035 /*
4036  *    Function Name : XimRequestDispatch()
4037  *    Description   : dispatch all requests of X11 IM protocol.
4038  *    Parameter     :
4039  *      <none>
4040  *    Returned Value:
4041  *      <none>
4042  */
4043 #if NeedFunctionPrototypes
4044 void
XimRequestDispatch(void)4045 XimRequestDispatch (void)
4046 #else
4047 void
4048 XimRequestDispatch ()
4049 #endif                          /* NeedFunctionPrototypes */
4050 {
4051   XimRequestPacket req_data;
4052   XimRequestPacket *req = &req_data;
4053   int ret;
4054 
4055   ret = cur_status = 0;
4056   if (RecvRequest (req) < 0)
4057     return;
4058 
4059   /* respond each request of protocol */
4060   switch (req->major_opcode)
4061     {
4062     case XIM_AUTH_NEXT:
4063       ret = SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
4064       break;
4065     case XIM_AUTH_REPLY:
4066       ret = SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
4067       break;
4068     case XIM_CONNECT:
4069       ret = RecvConnect (req);
4070       break;
4071     case XIM_DISCONNECT:
4072       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4073       ret = RecvDisconnect (req);
4074       break;
4075     case XIM_OPEN:
4076       cur_status = XIM_IMID_VALID;
4077       ret = RecvOpen (req);
4078       break;
4079     case XIM_CLOSE:
4080       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4081       ret = RecvClose (req);
4082       break;
4083     case XIM_ENCODING_NEGOTIATION:
4084       cur_status = XIM_IMID_VALID;
4085       ret = RecvEncodingNegotiation (req);
4086       break;
4087     case XIM_QUERY_EXTENSION:
4088       cur_status = XIM_IMID_VALID;
4089       ret = RecvQueryExtension (req);
4090       break;
4091     case XIM_SET_IM_VALUES:
4092       cur_status = XIM_IMID_VALID;
4093       ret = RecvSetIMValues (req);
4094       break;
4095     case XIM_GET_IM_VALUES:
4096       cur_status = XIM_IMID_VALID;
4097       ret = RecvGetIMValues (req);
4098       break;
4099     case XIM_CREATE_IC:
4100       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4101       ret = RecvCreateIC (req);
4102       break;
4103     case XIM_DESTROY_IC:
4104       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4105       ret = RecvDestroyIC (req);
4106       break;
4107     case XIM_SET_IC_VALUES:
4108       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4109       ret = RecvSetICValues (req);
4110       break;
4111     case XIM_GET_IC_VALUES:
4112       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4113       ret = RecvGetICValues (req);
4114       break;
4115     case XIM_SET_IC_FOCUS:
4116       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4117       (void) RecvSetICFocus (req);      /* asyncronous request */
4118       break;
4119     case XIM_UNSET_IC_FOCUS:
4120       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4121       (void) RecvUnsetICFocus (req);    /* asyncronous request */
4122       break;
4123     case XIM_TRIGGER_NOTIFY:
4124       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4125 #ifdef DYNAMIC_EVENT_FLOW_MODEL
4126       ret = RecvTriggerNotify (req);
4127 #else
4128       ret = 0;
4129 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
4130       break;
4131     case XIM_FORWARD_EVENT:
4132       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4133       ret = RecvForwardEvent (req);
4134       break;
4135     case XIM_RESET_IC:
4136       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4137       ret = RecvResetIC (req);
4138       break;
4139     case XIM_SYNC:
4140       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4141       ret = RecvSync (req);
4142       break;
4143     case XIM_SYNC_REPLY:
4144       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4145       (void) RecvSyncReply (req);       /* don't need send anything */
4146       break;
4147 #ifdef CALLBACKS
4148     case XIM_PREEDIT_START_REPLY:
4149       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4150       ret = RecvPreeditStartReply (req);
4151       break;
4152     case XIM_PREEDIT_CARET_REPLY:
4153       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4154       ret = RecvPreeditCaretReply (req);
4155       break;
4156 #endif /* CALLBACKS */
4157     case XIM_STR_CONVERSION_REPLY:
4158       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4159       ret = RecvStrConversionReply (req);
4160       break;
4161 #if defined(EXT_MOVE) || defined(SPOT)
4162     case XIM_EXT_MOVE:
4163       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4164       (void) RecvExtMove (req); /* asyncronous request */
4165       break;
4166 #endif /* defined(EXT_MOVE) || defined(SPOT) */
4167     case XIM_ERROR:
4168       cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4169       (void) RecvError (req);   /* asyncronous request */
4170       break;
4171     default:
4172       ret = XIM_BadProtocol;
4173     }
4174   if (ret)
4175     SendError (ret);
4176   FREE (req->data);
4177 }
4178 
4179 /*
4180  *    Function Name : XimPreConnect()
4181  *    Description   : make a base for preconnection with IM client. This
4182  *                    includes to create all selection atoms, names and
4183  *                    properties, plus some initial steps.
4184  *    Parameter     :
4185  *      port        : TCP/IP port number used in this IM protocol.
4186  *      root        : default root client.
4187  *    Returned Value:
4188  *      = 0         : successed.
4189  *      = -1        : error, failed to make preconnection.
4190  */
4191 #if NeedFunctionPrototypes
4192 int
XimPreConnect(unsigned short port,XIMRootRec * root)4193 XimPreConnect (unsigned short port,     /* port number 38036/tcp of xwnmo */
4194                XIMRootRec * root)
4195 #else
4196 int
4197 XimPreConnect (port, root)
4198      unsigned short port;       /* port number 38036/tcp of xwnmo */
4199      XIMRootRec *root;
4200 #endif /* NeedFunctionPrototypes */
4201 {
4202   char atom_name[BUFFER_MAX];
4203   char hostname[BUFFER_MAX];
4204   int len;
4205 
4206   /*
4207    * make server atom:  @server=xwnmo
4208    */
4209   (void) sprintf (atom_name, "%s%s", XIM_SERVER_CATEGORY, XIM_SERVER_NAME);
4210   if ((server_id = XInternAtom (dpy, atom_name, True)) != (Atom) None)
4211     {
4212       if (XGetSelectionOwner (dpy, server_id) != (Window) None)
4213         {
4214           print_out ("Another server has been already running.");
4215           return -1;
4216         }
4217     }
4218   else
4219     {
4220       server_id = XInternAtom (dpy, atom_name, False);
4221     }
4222 
4223   if (AppendServerToProperty (dpy, root->root_window, server_id) == False)
4224     return -1;
4225 
4226   /*
4227    * make target XIM_LOCALES:  "@locale=ja,ja_JP,..."
4228    */
4229   (void) strcpy (atom_name, XIM_LOCAL_CATEGORY);
4230   locale_supported = (unsigned char *) GetLocaleSupported ();
4231   len = strlen (atom_name);
4232   if (!(locale_prop = (unsigned char *) Malloc (len + strlen (locale_supported) + 1)))
4233     {
4234       malloc_error ("allocation of locale property");
4235       return -1;
4236     }
4237   locale_target = XInternAtom (dpy, XIM_LOCALES, False);
4238   (void) strcpy (locale_prop, atom_name);
4239   (void) strcat (locale_prop, locale_supported);
4240   locale_supported = locale_prop + len;
4241 
4242   /*
4243    * make target XIM_TRANSPORT:  "tcp/hostname:port"
4244    */
4245   (void) XmuGetHostname (hostname, (sizeof hostname));
4246   (void) sprintf (atom_name, "%stcp/%s:%u", XIM_TRANSPORT_CATEGORY, hostname, port);
4247   len = strlen (atom_name);
4248   if (!(transport_prop = (unsigned char *) Malloc (len + 1)))
4249     {
4250       malloc_error ("allocation of transport property");
4251       return -1;
4252     }
4253   transport_target = XInternAtom (dpy, XIM_TRANSPORT, False);
4254   (void) strcpy (transport_prop, atom_name);
4255 
4256   XSetSelectionOwner (dpy, server_id, root->ximclient->w, 0L);
4257 
4258   InitiateProtocol ();
4259 
4260   return 0;
4261 }
4262 
4263 /*
4264  *    Function Name : XimConvertTarget()
4265  *    Description   : convert a selection target and send its property
4266  *                    to client.  This is in preconnection phase.
4267  *    Parameter     :
4268  *      dpy         : pointer to X display.
4269  *      event       : selection event.
4270  *    Returned Value:
4271  *      <none>
4272  */
4273 #if NeedFunctionPrototypes
4274 void
XimConvertTarget(Display * dpy,XSelectionRequestEvent * event)4275 XimConvertTarget (Display * dpy, XSelectionRequestEvent * event)
4276 #else
4277 void
4278 XimConvertTarget (dpy, event)
4279      Display *dpy;
4280      XSelectionRequestEvent *event;
4281 #endif /* NeedFunctionPrototypes */
4282 {
4283   XSelectionEvent new;
4284   unsigned char *string = (unsigned char *) NULL;
4285 
4286   bzero (&new, sizeof (XSelectionEvent));
4287   new.type = SelectionNotify;
4288   new.serial = event->serial;
4289   new.display = event->display;
4290   new.requestor = event->requestor;
4291   new.selection = event->selection;
4292   new.target = event->target;
4293   new.time = event->time;
4294   new.property = event->property;
4295 
4296   if (event->selection == server_id)
4297     {
4298       if (event->target == locale_target)
4299         string = locale_prop;
4300       else if (event->target == transport_target)
4301         string = transport_prop;
4302       if (string)
4303         {
4304           XChangeProperty (dpy, event->requestor, event->property, event->target, 8, PropModeReplace, string, strlen ((char *) string));
4305           XFlush (dpy);
4306         }
4307     }
4308   XSendEvent (dpy, event->requestor, False, NoEventMask, (XEvent *) & new);
4309 }
4310 
4311 /*
4312  *    Function Name : xim_send_ct()
4313  *    Description   : similar to Xsi IM send_ct().
4314  *    Parameter     :
4315  *      ct          : CT string
4316  *      ct_len      : length of string in byte.
4317  *    Returned Value:
4318  *      = 0         : successed.
4319  *      > 0         : error, the number is error code.
4320  */
4321 #if NeedFunctionPrototypes
4322 int
xim_send_ct(register char * ct,register int ct_len)4323 xim_send_ct (register char *ct, register int ct_len)
4324 #else
4325 int
4326 xim_send_ct (ct, ct_len)
4327      register char *ct;
4328      register int ct_len;
4329 #endif /* NeedFunctionPrototypes */
4330 {
4331   return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupChars, (KeySym) 0, ct, ct_len);
4332 }
4333 
4334 /*
4335  *    Function Name : xim_send_keysym()
4336  *    Description   : similar to Xsi IM send_keysym().
4337  *    Parameter     :
4338  *      keysym      : keysym code
4339  *      str         : keysym character.
4340  *    Returned Value:
4341  *      = 0         : successed.
4342  *      > 0         : error, the number is error code.
4343  */
4344 #if NeedFunctionPrototypes
4345 int
xim_send_keysym(KeySym keysym,char str)4346 xim_send_keysym (KeySym keysym, char str)
4347 #else
4348 int
4349 xim_send_keysym (keysym, str)
4350      KeySym keysym;
4351      char str;
4352 #endif /* NeedFunctionPrototypes */
4353 {
4354   if (keysym < 0x20)
4355     {
4356       keysym |= 0xff00;
4357       return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupKeySym, keysym, (char *) NULL, 0);
4358     }
4359   else
4360     {
4361       str &= 0xff;
4362       return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupBoth, keysym, &str, 1);
4363     }
4364 }
4365 
4366 /*
4367  *    Function Name : xim_send_nofilter()
4368  *    Description   : similar to Xsi IM send_nofilter().
4369  *    Parameter     :
4370  *      <none>
4371  *    Returned Value:
4372  *      = 0         : successed.
4373  *      > 0         : error, the number is error code.
4374  */
4375 #if NeedFunctionPrototypes
4376 int
xim_send_nofilter(void)4377 xim_send_nofilter (void)
4378 #else
4379 int
4380 xim_send_nofilter ()
4381 #endif                          /* NeedFunctionPrototypes */
4382 {
4383   XEvent *xev = CUR_CLIENT_EVENT ();
4384   int serial = XIM_SERIALNUMBER (((XAnyEvent *) xev)->serial);
4385 
4386   return SendForwardEvent (CUR_IM_ID (), CUR_IC_ID (), serial, xev);
4387 }
4388 
4389 #ifdef CALLBACKS
4390 
4391 /*
4392  *    Function Name : xim_send_preeditstart()
4393  *    Description   : similar to Xsi IM send_preeditstart().
4394  *    Parameter     :
4395  *      <none>
4396  *    Returned Value:
4397  *      <none>
4398  */
4399 #if NeedFunctionPrototypes
4400 void
xim_send_preeditstart(void)4401 xim_send_preeditstart (void)
4402 #else
4403 void
4404 xim_send_preeditstart ()
4405 #endif                          /* NeedFunctionPrototypes */
4406 {
4407   (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_START, 0);
4408 }
4409 
4410 /*
4411  *    Function Name : xim_send_preeditdraw()
4412  *    Description   : similar to Xsi IM send_preeditdraw().
4413  *    Parameter     :
4414  *      caret       : caret
4415  *      first       : first of change.
4416  *      chg_len     : length of change.
4417  *      str         : wchar string.
4418  *      len         : length of string in wchar.
4419  *      flg         : flag
4420  *    Returned Value:
4421  *      <none>
4422  */
4423 #if NeedFunctionPrototypes
4424 void
xim_send_preeditdraw(int caret,int first,int chg_len,wchar * str,int len,int flg)4425 xim_send_preeditdraw (int caret, int first, int chg_len, wchar * str, int len, int flg)
4426 #else
4427 void
4428 xim_send_preeditdraw (caret, first, chg_len, str, len, flg)
4429      int caret;
4430      int first;
4431      int chg_len;
4432      wchar *str;
4433      int len;
4434      int flg;
4435 #endif /* NeedFunctionPrototypes */
4436 {
4437   unsigned short fb = 0;
4438   int send_len;
4439   XIMFeedback xim_fb;
4440 
4441   if (str)
4442     {
4443       while (1)
4444         {
4445           send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
4446           if (send_len < -1)
4447             {
4448               return;
4449             }
4450           else if (send_len == -1)
4451             {
4452               if (realloc_ct_buf () < 0)
4453                 return;
4454             }
4455           else
4456             {
4457               break;
4458             }
4459         }
4460     }
4461   else
4462     {
4463       send_len = 0;
4464     }
4465   if (flg & REV_FLAG)
4466     fb |= XIMReverse;
4467   if (flg & UNDER_FLAG)
4468     fb |= XIMUnderline;
4469   if (flg & BOLD_FLAG)
4470     fb |= XIMHighlight;
4471 
4472   xim_fb = (XIMFeedback) fb;
4473   (void) SendPreeditDraw (CUR_IM_ID (), CUR_IC_ID (), caret, first, chg_len, ct_buf, send_len, (XIMFeedback *) & xim_fb, 1);
4474 }
4475 
4476 /*
4477  *    Function Name : xim_send_preeditcaret()
4478  *    Description   : similar to Xsi IM send_preeditcaret().
4479  *    Parameter     :
4480  *      pos         : position
4481  *      flg         : flag
4482  *    Returned Value:
4483  *      <none>
4484  */
4485 #if NeedFunctionPrototypes
4486 void
xim_send_preeditcaret(int flg,int pos)4487 xim_send_preeditcaret (int flg, int pos)
4488 #else
4489 void
4490 xim_send_preeditcaret (flg, pos)
4491      int flg;
4492      int pos;
4493 #endif /* NeedFunctionPrototypes */
4494 {
4495   int style;
4496 
4497   if (flg)
4498     {
4499       style = XIMIsPrimary;
4500     }
4501   else
4502     {
4503       style = XIMIsInvisible;
4504     }
4505   (void) SendPreeditCaret (CUR_IM_ID (), CUR_IC_ID (), pos, XIMAbsolutePosition, style);
4506 }
4507 
4508 /*
4509  *    Function Name : xim_send_preeditdone()
4510  *    Description   : similar to Xsi IM send_preeditdone().
4511  *    Parameter     :
4512  *      <none>
4513  *    Returned Value:
4514  *      <none>
4515  */
4516 #if NeedFunctionPrototypes
4517 void
xim_send_preeditdone(void)4518 xim_send_preeditdone (void)
4519 #else
4520 void
4521 xim_send_preeditdone ()
4522 #endif                          /* NeedFunctionPrototypes */
4523 {
4524   (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_DONE, 0);
4525 }
4526 
4527 /*
4528  *    Function Name : xim_send_statusstart()
4529  *    Description   : similar to Xsi IM send_statusstart().
4530  *    Parameter     :
4531  *      <none>
4532  *    Returned Value:
4533  *      <none>
4534  */
4535 #if NeedFunctionPrototypes
4536 void
xim_send_statusstart(void)4537 xim_send_statusstart (void)
4538 #else
4539 void
4540 xim_send_statusstart ()
4541 #endif                          /* NeedFunctionPrototypes */
4542 {
4543   (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_START, 0);
4544 }
4545 
4546 /*
4547  *    Function Name : xim_send_statusdraw()
4548  *    Description   : similar to Xsi IM send_statusdraw().
4549  *    Parameter     :
4550  *      str         : wchar string.
4551  *      len         : length of string in wchar.
4552  *    Returned Value:
4553  *      <none>
4554  */
4555 #if NeedFunctionPrototypes
4556 void
xim_send_statusdraw(wchar * str,int len)4557 xim_send_statusdraw (wchar * str, int len)
4558 #else
4559 void
4560 xim_send_statusdraw (str, len)
4561      wchar *str;
4562      int len;
4563 #endif /* NeedFunctionPrototypes */
4564 {
4565   int send_len;
4566 
4567   /* refer to callback.c: send_statusdraw() */
4568   while (1)
4569     {
4570       send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
4571       if (send_len < -1)
4572         {
4573           return;
4574         }
4575       else if (send_len == -1)
4576         {
4577           if (realloc_ct_buf () < 0)
4578             return;
4579         }
4580       else
4581         {
4582           break;
4583         }
4584     }
4585   (void) SendStatusDraw (CUR_IM_ID (), CUR_IC_ID (), XIMTextType, ct_buf, send_len, (XIMFeedback *) NULL, 0, (PIXMAP) 0);
4586 }
4587 
4588 /*
4589  *    Function Name : xim_send_statusdone()
4590  *    Description   : similar to Xsi IM send_statusdone().
4591  *    Parameter     :
4592  *      <none>
4593  *    Returned Value:
4594  *      <none>
4595  */
4596 #if NeedFunctionPrototypes
4597 void
xim_send_statusdone(void)4598 xim_send_statusdone (void)
4599 #else
4600 void
4601 xim_send_statusdone ()
4602 #endif                          /* NeedFunctionPrototypes */
4603 {
4604   (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_DONE, 0);
4605 }
4606 
4607 #endif /* CALLBACKS */
4608 
4609 #endif /* !X11R5 */
4610