upload tizen2.0 source
[framework/uifw/xorg/lib/libx11.git] / modules / im / ximcp / imDefIc.c
1 /*
2  * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 /******************************************************************
24
25            Copyright 1992, 1993, 1994 by FUJITSU LIMITED
26
27 Permission to use, copy, modify, distribute, and sell this software
28 and its documentation for any purpose is hereby granted without fee,
29 provided that the above copyright notice appear in all copies and
30 that both that copyright notice and this permission notice appear
31 in supporting documentation, and that the name of FUJITSU LIMITED
32 not be used in advertising or publicity pertaining to distribution
33 of the software without specific, written prior permission.
34 FUJITSU LIMITED makes no representations about the suitability of
35 this software for any purpose.
36 It is provided "as is" without express or implied warranty.
37
38 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44 PERFORMANCE OF THIS SOFTWARE.
45
46   Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
47           Takashi Fujiwara     FUJITSU LIMITED
48                                fujiwara@a80.tech.yk.fujitsu.co.jp
49
50 ******************************************************************/
51
52 #ifdef HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55 #include "Xlibint.h"
56 #include "Xlcint.h"
57 #include "Ximint.h"
58
59 Private Bool
60 _XimCreateICCheck(
61     Xim          im,
62     INT16        len,
63     XPointer     data,
64     XPointer     arg)
65 {
66     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
67     CARD8        major_opcode = *((CARD8 *)data);
68     CARD8        minor_opcode = *((CARD8 *)data + 1);
69     XIMID        imid = buf_s[0];
70
71     if ((major_opcode == XIM_CREATE_IC_REPLY)
72      && (minor_opcode == 0)
73      && (imid == im->private.proto.imid))
74         return True;
75     if ((major_opcode == XIM_ERROR)
76      && (minor_opcode == 0)
77      && (buf_s[2] & XIM_IMID_VALID)
78      && (imid == im->private.proto.imid))
79         return True;
80     return False;
81 }
82
83 #ifdef XIM_CONNECTABLE
84 Public Bool
85 _XimReCreateIC(ic)
86     Xic                  ic;
87 {
88     Xim                  im = (Xim)ic->core.im;
89     Xic                  save_ic;
90     XIMResourceList      res;
91     unsigned int         num;
92     XIMStyle             input_style = ic->core.input_style;
93     XimDefICValues       ic_values;
94     INT16                len;
95     CARD16              *buf_s;
96     char                *tmp;
97     CARD32               tmp_buf32[BUFSIZE/4];
98     char                *tmp_buf = (char *)tmp_buf32;
99     char                *buf;
100     int                  buf_size;
101     char                *data;
102     int                  data_len;
103     int                  ret_len;
104     int                  total;
105     int                  idx;
106     CARD32               reply32[BUFSIZE/4];
107     char                *reply = (char *)reply32;
108     XPointer             preply;
109     int                  ret_code;
110
111     if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec))))
112         return False;
113     memcpy((char *)save_ic, (char *)ic, sizeof(XicRec));
114
115     ic->core.filter_events = im->private.proto.forward_event_mask;
116     ic->private.proto.forward_event_mask =
117                                 im->private.proto.forward_event_mask;
118     ic->private.proto.synchronous_event_mask =
119                                 im->private.proto.synchronous_event_mask;
120
121     num = im->core.ic_num_resources;
122     buf_size = sizeof(XIMResource) * num;
123     if (!(res = (XIMResourceList)Xmalloc(buf_size)))
124         goto ErrorOnReCreateIC;
125     (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size);
126     ic->private.proto.ic_resources     = res;
127     ic->private.proto.ic_num_resources = num;
128
129     num = im->private.proto.ic_num_inner_resources;
130     buf_size = sizeof(XIMResource) * num;
131     if (!(res = (XIMResourceList)Xmalloc(buf_size)))
132         goto ErrorOnReCreateIC;
133     (void)memcpy((char *)res,
134                         (char *)im->private.proto.ic_inner_resources, buf_size);
135     ic->private.proto.ic_inner_resources     = res;
136     ic->private.proto.ic_num_inner_resources = num;
137
138     _XimSetICMode(ic->private.proto.ic_resources,
139                         ic->private.proto.ic_num_resources, input_style);
140
141     _XimSetICMode(ic->private.proto.ic_inner_resources,
142                         ic->private.proto.ic_num_inner_resources, input_style);
143
144     _XimGetCurrentICValues(ic, &ic_values);
145     buf = tmp_buf;
146     buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
147     data_len = BUFSIZE - buf_size;
148     total = 0;
149     idx = 0;
150     for (;;) {
151         data = &buf[buf_size];
152         if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources,
153                 ic->private.proto.ic_num_resources, &idx, data, data_len,
154                 &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) {
155             if (buf != tmp_buf)
156                 Xfree(buf);
157             goto ErrorOnReCreateIC;
158         }
159
160         total += ret_len;
161         if (idx == -1) {
162             break;
163         }
164
165         buf_size += ret_len;
166         if (buf == tmp_buf) {
167             if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
168                 goto ErrorOnReCreateIC;
169             }
170             memcpy(tmp, buf, buf_size);
171             buf = tmp;
172         } else {
173             if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
174                 Xfree(buf);
175                 goto ErrorOnReCreateIC;
176             }
177             buf = tmp;
178         }
179     }
180
181     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
182     buf_s[0] = im->private.proto.imid;
183     buf_s[1] = (INT16)total;
184
185     len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
186     _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
187     if (!(_XimWrite(im, len, (XPointer)buf))) {
188         if (buf != tmp_buf)
189             Xfree(buf);
190         goto ErrorOnReCreateIC;
191     }
192     _XimFlush(im);
193     if (buf != tmp_buf)
194         Xfree(buf);
195     ic->private.proto.waitCallback = True;
196     buf_size = BUFSIZE;
197     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
198                                                  _XimCreateICCheck, 0);
199     if (ret_code == XIM_TRUE) {
200         preply = reply;
201     } else if (ret_code == XIM_OVERFLOW) {
202         if (len <= 0) {
203             preply = reply;
204         } else {
205             buf_size = (int)len;
206             preply = (XPointer)Xmalloc(buf_size);
207             ret_code = _XimRead(im, &len, preply, buf_size,
208                                                  _XimCreateICCheck, 0);
209             if (ret_code != XIM_TRUE) {
210                 Xfree(preply);
211                 ic->private.proto.waitCallback = False;
212                 goto ErrorOnReCreateIC;
213             }
214         }
215     } else {
216         ic->private.proto.waitCallback = False;
217         goto ErrorOnReCreateIC;
218     }
219     ic->private.proto.waitCallback = False;
220     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
221     if (*((CARD8 *)preply) == XIM_ERROR) {
222         _XimProcError(im, 0, (XPointer)&buf_s[3]);
223         if (reply != preply)
224             Xfree(preply);
225         goto ErrorOnReCreateIC;
226     }
227
228     ic->private.proto.icid = buf_s[1];          /* icid */
229     if (reply != preply)
230         Xfree(preply);
231
232     _XimRegisterFilter(ic);
233     MARK_IC_CONNECTED(ic);
234     if (save_ic->private.proto.ic_resources)
235         Xfree(save_ic->private.proto.ic_resources);
236     if (save_ic->private.proto.ic_inner_resources)
237         Xfree(save_ic->private.proto.ic_inner_resources);
238     Xfree(save_ic);
239     return True;
240
241 ErrorOnReCreateIC:
242     memcpy((char *)ic, (char *)save_ic, sizeof(XicRec));
243     Xfree(save_ic);
244     return False;
245 }
246
247 Private char *
248 _XimDelayModeGetICValues(ic, arg)
249     Xic                  ic;
250     XIMArg              *arg;
251 {
252     XimDefICValues       ic_values;
253
254     _XimGetCurrentICValues(ic, &ic_values);
255     return  _XimGetICValueData(ic, (XPointer)&ic_values,
256                                 ic->private.proto.ic_resources,
257                                 ic->private.proto.ic_num_resources,
258                                 arg, XIM_GETICVALUES);
259 }
260 #endif /* XIM_CONNECTABLE */
261
262 Private Bool
263 _XimGetICValuesCheck(
264     Xim          im,
265     INT16        len,
266     XPointer     data,
267     XPointer     arg)
268 {
269     Xic          ic = (Xic)arg;
270     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
271     CARD8        major_opcode = *((CARD8 *)data);
272     CARD8        minor_opcode = *((CARD8 *)data + 1);
273     XIMID        imid = buf_s[0];
274     XICID        icid = buf_s[1];
275
276     if ((major_opcode == XIM_GET_IC_VALUES_REPLY)
277      && (minor_opcode == 0)
278      && (imid == im->private.proto.imid)
279      && (icid == ic->private.proto.icid))
280         return True;
281     if ((major_opcode == XIM_ERROR)
282      && (minor_opcode == 0)
283      && (buf_s[2] & XIM_IMID_VALID)
284      && (imid == im->private.proto.imid)
285      && (buf_s[2] & XIM_ICID_VALID)
286      && (icid == ic->private.proto.icid))
287         return True;
288     return False;
289 }
290
291 Private char *
292 _XimProtoGetICValues(
293     XIC                  xic,
294     XIMArg              *arg)
295 {
296     Xic                  ic = (Xic)xic;
297     Xim                  im = (Xim)ic->core.im;
298     register XIMArg     *p;
299     register XIMArg     *pp;
300     register int         n;
301     CARD8               *buf;
302     CARD16              *buf_s;
303     INT16                len;
304     CARD32               reply32[BUFSIZE/4];
305     char                *reply = (char *)reply32;
306     XPointer             preply = NULL;
307     int                  buf_size;
308     int                  ret_code;
309     char                *makeid_name;
310     char                *decode_name;
311     CARD16              *data = NULL;
312     INT16                data_len = 0;
313
314 #ifndef XIM_CONNECTABLE
315     if (!IS_IC_CONNECTED(ic))
316         return arg->name;
317 #else
318     if (!IS_IC_CONNECTED(ic)) {
319         if (IS_CONNECTABLE(im)) {
320             if (_XimConnectServer(im)) {
321                 if (!_XimReCreateIC(ic)) {
322                     _XimDelayModeSetAttr(im);
323                     return _XimDelayModeGetICValues(ic, arg);
324                 }
325             } else {
326                 return _XimDelayModeGetICValues(ic, arg);
327             }
328         } else {
329             return arg->name;
330         }
331     }
332 #endif /* XIM_CONNECTABLE */
333
334     for (n = 0, p = arg; p && p->name; p++) {
335         n++;
336         if ((strcmp(p->name, XNPreeditAttributes) == 0)
337          || (strcmp(p->name, XNStatusAttributes) == 0)) {
338              n++;
339              for (pp = (XIMArg *)p->value; pp && pp->name; pp++)
340                 n++;
341         }
342     }
343
344     if (!n)
345         return (char *)NULL;
346
347     buf_size =  sizeof(CARD16) * n;
348     buf_size += XIM_HEADER_SIZE
349              + sizeof(CARD16)
350              + sizeof(CARD16)
351              + sizeof(INT16)
352              + XIM_PAD(2 + buf_size);
353
354     if (!(buf = (CARD8 *)Xmalloc(buf_size)))
355         return arg->name;
356     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
357
358     makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources,
359                                 ic->private.proto.ic_num_resources, arg,
360                                 &buf_s[3], &len, XIM_GETICVALUES);
361
362     if (len > 0) {
363         buf_s[0] = im->private.proto.imid;              /* imid */
364         buf_s[1] = ic->private.proto.icid;              /* icid */
365         buf_s[2] = len;                         /* length of ic-attr-id */
366         len += sizeof(INT16);                       /* sizeof length of attr */
367         XIM_SET_PAD(&buf_s[2], len);            /* pad */
368         len += sizeof(CARD16)                   /* sizeof imid */
369              + sizeof(CARD16);                  /* sizeof icid */
370
371         _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len);
372         if (!(_XimWrite(im, len, (XPointer)buf))) {
373             Xfree(buf);
374             return arg->name;
375         }
376         _XimFlush(im);
377         Xfree(buf);
378         buf_size = BUFSIZE;
379         ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
380                                  _XimGetICValuesCheck, (XPointer)ic);
381         if (ret_code == XIM_TRUE) {
382             preply = reply;
383         } else if (ret_code == XIM_OVERFLOW) {
384             if (len <= 0) {
385                 preply = reply;
386             } else {
387                 buf_size = (int)len;
388                 preply = (XPointer)Xmalloc(len);
389                 ret_code = _XimRead(im, &len, preply, buf_size,
390                                 _XimGetICValuesCheck, (XPointer)ic);
391                 if (ret_code != XIM_TRUE) {
392                     if (preply != reply)
393                         Xfree(preply);
394                     return arg->name;
395                 }
396             }
397         } else {
398             return arg->name;
399         }
400         buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
401         if (*((CARD8 *)preply) == XIM_ERROR) {
402             _XimProcError(im, 0, (XPointer)&buf_s[3]);
403             if (reply != preply)
404                 Xfree(preply);
405             return arg->name;
406         }
407         data = &buf_s[4];
408         data_len = buf_s[2];
409     }
410     else if (len < 0) {
411         return arg->name;
412     }
413
414     decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
415                         ic->private.proto.ic_num_resources, data, data_len,
416                         arg, XIM_GETICVALUES);
417     if (reply != preply)
418         Xfree(preply);
419
420     if (decode_name)
421         return decode_name;
422     else
423         return makeid_name;
424 }
425
426 #ifdef XIM_CONNECTABLE
427 Private Bool
428 _XimCheckNestQuarkList(quark_list, num_quark, quark, separator)
429     XrmQuark            *quark_list;
430     int                  num_quark;
431     XrmQuark             quark;
432     XrmQuark             separator;
433 {
434     register int         i;
435
436     for (i = 0; i < num_quark; i++) {
437         if (quark_list[i] == separator) {
438             break;
439         }
440         if (quark_list[i] == quark) {
441             return True;
442         }
443     }
444     return False;
445 }
446
447 Private Bool
448 _XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator)
449     XrmQuark            **quark_list;
450     int                   idx;
451     int                  *num_quark;
452     XIMArg               *arg;
453     XrmQuark              separator;
454 {
455     XrmQuark             *q_list = *quark_list;
456     int                   n_quark = *num_quark;
457     register XIMArg      *p;
458     XrmQuark              quark;
459     XrmQuark             *tmp;
460     register int          i;
461
462     for (p = arg; p && p->name; p++) {
463         quark = XrmStringToQuark(p->name);
464         if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx,
465                                                         quark, separator)) {
466             continue;
467         }
468         if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) {
469             *quark_list = q_list;
470             *num_quark = n_quark;
471             return False;
472         }
473         n_quark++;
474         for (i = 0; i < idx; i++) {
475             tmp[i] = q_list[i];
476         }
477         tmp[i] = quark;
478         for (i = idx  + 1; i < n_quark; i++) {
479             tmp[i] = q_list[i - 1];
480         }
481         q_list = tmp;
482     }
483     *quark_list = q_list;
484     *num_quark = n_quark;
485     return True;
486 }
487
488 Private Bool
489 _XimCheckICQuarkList(quark_list, num_quark, quark, idx)
490     XrmQuark            *quark_list;
491     int                  num_quark;
492     XrmQuark             quark;
493     int                 *idx;
494 {
495     register int         i;
496
497     for (i = 0; i < num_quark; i++) {
498         if (quark_list[i] == quark) {
499             *idx = i;
500             return True;
501         }
502     }
503     return False;
504 }
505
506 Private Bool
507 _XimSaveICValues(ic, arg)
508     Xic                  ic;
509     XIMArg              *arg;
510 {
511     register XIMArg     *p;
512     register int         n;
513     XrmQuark            *quark_list;
514     XrmQuark            *tmp;
515     XrmQuark             quark;
516     int                  num_quark;
517     XrmQuark             pre_quark;
518     XrmQuark             sts_quark;
519     XrmQuark             separator;
520     int                  idx;
521
522     pre_quark = XrmStringToQuark(XNPreeditAttributes);
523     sts_quark = XrmStringToQuark(XNStatusAttributes);
524     separator = XrmStringToQuark(XNSeparatorofNestedList);
525
526     if (quark_list = ic->private.proto.saved_icvalues) {
527         num_quark = ic->private.proto.num_saved_icvalues;
528         for (p = arg; p && p->name; p++) {
529             quark = XrmStringToQuark(p->name);
530             if ((quark == pre_quark) || (quark == sts_quark)) {
531                 if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
532                     register XIMArg     *pp;
533                     int                  nn;
534                     XrmQuark            *q_list;
535
536                     for (pp = (XIMArg *)p->value, nn = 0;
537                                                 pp && pp->name; pp++, nn++);
538                     if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
539                                 (sizeof(XrmQuark) * (num_quark + nn + 2))))) {
540                         ic->private.proto.saved_icvalues = quark_list;
541                         ic->private.proto.num_saved_icvalues = num_quark;
542                         return False;
543                     }
544                     quark_list = tmp;
545                     q_list = &quark_list[num_quark];
546                     num_quark += nn + 2;
547                     *q_list++ = quark;
548                     for (pp = (XIMArg *)p->value;
549                                         pp && pp->name; pp++, quark_list++) {
550                         *q_list = XrmStringToQuark(pp->name);
551                     }
552                     *q_list = separator;
553                 } else {
554                     if (!_XimCheckNestedQuarkList(&quark_list, idx + 1,
555                                 &num_quark, (XIMArg *)p->value, separator)) {
556                         ic->private.proto.saved_icvalues = quark_list;
557                         ic->private.proto.num_saved_icvalues = num_quark;
558                         return False;
559                     }
560                 }
561             } else {
562                 if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
563                     continue;
564                 }
565                 if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
566                                 (sizeof(XrmQuark) * (num_quark + 1))))) {
567                     ic->private.proto.saved_icvalues = quark_list;
568                     ic->private.proto.num_saved_icvalues = num_quark;
569                     return False;
570                 }
571                 quark_list = tmp;
572                 quark_list[num_quark] = quark;
573                 num_quark++;
574             }
575         }
576         ic->private.proto.saved_icvalues = quark_list;
577         ic->private.proto.num_saved_icvalues = num_quark;
578         return True;
579     }
580
581     for (p = arg, n = 0; p && p->name; p++, n++) {
582         if ((!strcmp(p->name, XNPreeditAttributes))
583          || (!strcmp(p->name, XNStatusAttributes))) {
584             register XIMArg     *pp;
585             int                  nn;
586
587             for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++);
588             n += nn + 1;
589         }
590     }
591
592     if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
593         return False;
594     }
595
596     ic->private.proto.saved_icvalues = quark_list;
597     ic->private.proto.num_saved_icvalues = n;
598     for (p = arg; p && p->name; p++, quark_list++) {
599         *quark_list = XrmStringToQuark(p->name);
600         if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) {
601             register XIMArg     *pp;
602
603             quark_list++;
604             for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) {
605                 *quark_list = XrmStringToQuark(pp->name);
606             }
607             *quark_list = separator;
608         }
609     }
610     return True;
611 }
612
613 Private char *
614 _XimDelayModeSetICValues(ic, arg)
615     Xic                  ic;
616     XIMArg              *arg;
617 {
618     XimDefICValues       ic_values;
619     char                *name;
620
621     _XimGetCurrentICValues(ic, &ic_values);
622     name = _XimSetICValueData(ic, (XPointer)&ic_values,
623                         ic->private.proto.ic_resources,
624                         ic->private.proto.ic_num_resources,
625                         arg, XIM_SETICVALUES, False);
626     _XimSetCurrentICValues(ic, &ic_values);
627     return name;
628 }
629 #endif /* XIM_CONNECTABLE */
630
631 Private Bool
632 _XimSetICValuesCheck(
633     Xim          im,
634     INT16        len,
635     XPointer     data,
636     XPointer     arg)
637 {
638     Xic          ic = (Xic)arg;
639     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
640     CARD8        major_opcode = *((CARD8 *)data);
641     CARD8        minor_opcode = *((CARD8 *)data + 1);
642     XIMID        imid = buf_s[0];
643     XICID        icid = buf_s[1];
644
645     if ((major_opcode == XIM_SET_IC_VALUES_REPLY)
646      && (minor_opcode == 0)
647      && (imid == im->private.proto.imid)
648      && (icid == ic->private.proto.icid))
649         return True;
650     if ((major_opcode == XIM_ERROR)
651      && (minor_opcode == 0)
652      && (buf_s[2] & XIM_IMID_VALID)
653      && (imid == im->private.proto.imid)
654      && (buf_s[2] & XIM_ICID_VALID)
655      && (icid == ic->private.proto.icid))
656         return True;
657     return False;
658 }
659
660 Private char *
661 _XimProtoSetICValues(
662     XIC                  xic,
663     XIMArg              *arg)
664 {
665     Xic                  ic = (Xic)xic;
666     Xim                  im = (Xim)ic->core.im;
667     XimDefICValues       ic_values;
668     INT16                len;
669     CARD16              *buf_s;
670     char                *tmp;
671     CARD32               tmp_buf32[BUFSIZE/4];
672     char                *tmp_buf = (char *)tmp_buf32;
673     char                *buf;
674     int                  buf_size;
675     char                *data;
676     int                  data_len;
677     int                  ret_len;
678     int                  total;
679     XIMArg              *arg_ret;
680     CARD32               reply32[BUFSIZE/4];
681     char                *reply = (char *)reply32;
682     XPointer             preply = NULL;
683     int                  ret_code;
684     BITMASK32            flag = 0L;
685     char                *name;
686     char                *tmp_name = (arg) ? arg->name : NULL;
687
688 #ifndef XIM_CONNECTABLE
689     if (!IS_IC_CONNECTED(ic))
690         return tmp_name;
691 #else
692     if (!_XimSaveICValues(ic, arg))
693         return NULL;
694
695     if (!IS_IC_CONNECTED(ic)) {
696         if (IS_CONNECTABLE(im)) {
697             if (_XimConnectServer(im)) {
698                 if (!_XimReCreateIC(ic)) {
699                     _XimDelayModeSetAttr(im);
700                     return _XimDelayModeSetICValues(ic, arg);
701                 }
702             } else {
703                 return _XimDelayModeSetICValues(ic, arg);
704             }
705         } else {
706             return tmp_name;
707         }
708     }
709 #endif /* XIM_CONNECTABLE */
710
711     _XimGetCurrentICValues(ic, &ic_values);
712     buf = tmp_buf;
713     buf_size = XIM_HEADER_SIZE
714         + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16);
715     data_len = BUFSIZE - buf_size;
716     total = 0;
717     arg_ret = arg;
718     for (;;) {
719         data = &buf[buf_size];
720         if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
721                         ic->private.proto.ic_num_resources, arg, &arg_ret,
722                         data, data_len, &ret_len, (XPointer)&ic_values,
723                         &flag, XIM_SETICVALUES))) {
724             break;
725         }
726
727         total += ret_len;
728         if (!(arg = arg_ret)) {
729             break;
730         }
731
732         buf_size += ret_len;
733         if (buf == tmp_buf) {
734             if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
735                 return tmp_name;
736             }
737             memcpy(tmp, buf, buf_size);
738             buf = tmp;
739         } else {
740             if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
741                 Xfree(buf);
742                 return tmp_name;
743             }
744             buf = tmp;
745         }
746     }
747     _XimSetCurrentICValues(ic, &ic_values);
748
749     if (!total) {
750         return tmp_name;
751     }
752
753     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
754
755 #ifdef EXT_MOVE
756     if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total))
757         return name;
758 #endif
759
760     buf_s[0] = im->private.proto.imid;
761     buf_s[1] = ic->private.proto.icid;
762     buf_s[2] = (INT16)total;
763     buf_s[3] = 0;
764     len = (INT16)(sizeof(CARD16) + sizeof(CARD16)
765                                 + sizeof(INT16) + sizeof(CARD16) + total);
766
767     _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len);
768     if (!(_XimWrite(im, len, (XPointer)buf))) {
769         if (buf != tmp_buf)
770             Xfree(buf);
771         return tmp_name;
772     }
773     _XimFlush(im);
774     if (buf != tmp_buf)
775         Xfree(buf);
776     ic->private.proto.waitCallback = True;
777     buf_size = BUFSIZE;
778     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
779                                         _XimSetICValuesCheck, (XPointer)ic);
780     if (ret_code == XIM_TRUE) {
781         preply = reply;
782     } else if (ret_code == XIM_OVERFLOW) {
783         buf_size = (int)len;
784         preply = (XPointer)Xmalloc(buf_size);
785         ret_code = _XimRead(im, &len, preply, buf_size,
786                                         _XimSetICValuesCheck, (XPointer)ic);
787         if (ret_code != XIM_TRUE) {
788             Xfree(preply);
789             ic->private.proto.waitCallback = False;
790             return tmp_name;
791         }
792     } else {
793         ic->private.proto.waitCallback = False;
794         return tmp_name;
795     }
796     ic->private.proto.waitCallback = False;
797     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
798     if (*((CARD8 *)preply) == XIM_ERROR) {
799         _XimProcError(im, 0, (XPointer)&buf_s[3]);
800         if (reply != preply)
801             Xfree(preply);
802         return tmp_name;
803     }
804     if (reply != preply)
805         Xfree(preply);
806
807     return name;
808 }
809
810 Private Bool
811 _XimDestroyICCheck(
812     Xim          im,
813     INT16        len,
814     XPointer     data,
815     XPointer     arg)
816 {
817     Xic          ic = (Xic)arg;
818     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
819     CARD8        major_opcode = *((CARD8 *)data);
820     CARD8        minor_opcode = *((CARD8 *)data + 1);
821     XIMID        imid = buf_s[0];
822     XICID        icid = buf_s[1];
823     Bool         ret = False;
824
825     if ((major_opcode == XIM_DESTROY_IC_REPLY)
826      && (minor_opcode == 0)
827      && (imid == im->private.proto.imid)
828      && (icid == ic->private.proto.icid))
829         ret = True;
830     if ((major_opcode == XIM_ERROR)
831      && (minor_opcode == 0)
832      && (buf_s[2] & XIM_IMID_VALID)
833      && (imid == im->private.proto.imid)
834      && (buf_s[2] & XIM_ICID_VALID)
835      && (icid == ic->private.proto.icid))
836     ret = False;
837     return ret;
838 }
839
840 Private void
841 _XimProtoICFree(
842     Xic          ic)
843 {
844 #ifdef XIM_CONNECTABLE
845     Xim          im = (Xim)ic->core.im;
846 #endif
847
848     if (ic->private.proto.preedit_font) {
849         Xfree(ic->private.proto.preedit_font);
850         ic->private.proto.preedit_font = NULL;
851     }
852     if (ic->private.proto.status_font) {
853         Xfree(ic->private.proto.status_font);
854         ic->private.proto.status_font = NULL;
855     }
856     if (ic->private.proto.commit_info) {
857         _XimFreeCommitInfo(ic);
858         ic->private.proto.commit_info = NULL;
859     }
860     if (ic->private.proto.ic_inner_resources) {
861         Xfree(ic->private.proto.ic_inner_resources);
862         ic->private.proto.ic_inner_resources = NULL;
863     }
864
865 #ifdef XIM_CONNECTABLE
866     if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
867         return;
868     }
869 #endif /* XIM_CONNECTABLE */
870
871     if (ic->private.proto.saved_icvalues) {
872         Xfree(ic->private.proto.saved_icvalues);
873         ic->private.proto.saved_icvalues = NULL;
874     }
875     if (ic->private.proto.ic_resources) {
876         Xfree(ic->private.proto.ic_resources);
877         ic->private.proto.ic_resources = NULL;
878     }
879     if (ic->core.hotkey) {
880         Xfree(ic->core.hotkey);
881         ic->core.hotkey = NULL;
882     }
883
884     return;
885 }
886
887 Private void
888 _XimProtoDestroyIC(
889     XIC          xic)
890 {
891     Xic          ic = (Xic)xic;
892     Xim          im = (Xim)ic->core.im;
893     CARD32       buf32[BUFSIZE/4];
894     CARD8       *buf = (CARD8 *)buf32;
895     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
896     INT16        len;
897     CARD32       reply32[BUFSIZE/4];
898     char        *reply = (char *)reply32;
899     XPointer     preply;
900     int          buf_size;
901     int          ret_code;
902
903     if (IS_SERVER_CONNECTED(im)) {
904         buf_s[0] = im->private.proto.imid;              /* imid */
905         buf_s[1] = ic->private.proto.icid;              /* icid */
906
907         len = sizeof(CARD16)                    /* sizeof imid */
908             + sizeof(CARD16);                   /* sizeof icid */
909
910         _XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len);
911         (void)_XimWrite(im, len, (XPointer)buf);
912         _XimFlush(im);
913         buf_size = BUFSIZE;
914         ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
915                                         _XimDestroyICCheck, (XPointer)ic);
916         if (ret_code == XIM_OVERFLOW) {
917             buf_size = len;
918             preply = (XPointer)Xmalloc(buf_size);
919             (void)_XimRead(im, &len, preply, buf_size,
920                                         _XimDestroyICCheck, (XPointer)ic);
921             Xfree(preply);
922         }
923     }
924     UNMARK_IC_CONNECTED(ic);
925     _XimUnregisterFilter(ic);
926     _XimProtoICFree(ic);
927     return;
928 }
929
930 Private void
931 _XimProtoSetFocus(
932     XIC          xic)
933 {
934     Xic          ic = (Xic)xic;
935     Xim          im = (Xim)ic->core.im;
936     CARD32       buf32[BUFSIZE/4];
937     CARD8       *buf = (CARD8 *)buf32;
938     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
939     INT16        len;
940
941 #ifndef XIM_CONNECTABLE
942     if (!IS_IC_CONNECTED(ic))
943         return;
944 #else
945     if (!IS_IC_CONNECTED(ic)) {
946         if (IS_CONNECTABLE(im)) {
947             if (_XimConnectServer(im)) {
948                 if (!_XimReCreateIC(ic)) {
949                     _XimDelayModeSetAttr(im);
950                     return;
951                 }
952             } else {
953                 return;
954             }
955         } else {
956             return;
957         }
958     }
959 #endif /* XIM_CONNECTABLE */
960
961     buf_s[0] = im->private.proto.imid;          /* imid */
962     buf_s[1] = ic->private.proto.icid;          /* icid */
963
964     len = sizeof(CARD16)                        /* sizeof imid */
965         + sizeof(CARD16);                       /* sizeof icid */
966
967     _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len);
968     (void)_XimWrite(im, len, (XPointer)buf);
969     _XimFlush(im);
970
971     _XimRegisterFilter(ic);
972     return;
973 }
974
975 Private void
976 _XimProtoUnsetFocus(
977     XIC          xic)
978 {
979     Xic          ic = (Xic)xic;
980     Xim          im = (Xim)ic->core.im;
981     CARD32       buf32[BUFSIZE/4];
982     CARD8       *buf = (CARD8 *)buf32;
983     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
984     INT16        len;
985
986 #ifndef XIM_CONNECTABLE
987     if (!IS_IC_CONNECTED(ic))
988         return;
989 #else
990     if (!IS_IC_CONNECTED(ic)) {
991         if (IS_CONNECTABLE(im)) {
992             if (_XimConnectServer(im)) {
993                 if (!_XimReCreateIC(ic)) {
994                     _XimDelayModeSetAttr(im);
995                     return;
996                 }
997             } else {
998                 return;
999             }
1000         } else {
1001             return;
1002         }
1003     }
1004 #endif /* XIM_CONNECTABLE */
1005
1006     buf_s[0] = im->private.proto.imid;          /* imid */
1007     buf_s[1] = ic->private.proto.icid;          /* icid */
1008
1009     len = sizeof(CARD16)                        /* sizeof imid */
1010         + sizeof(CARD16);                       /* sizeof icid */
1011
1012     _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len);
1013     (void)_XimWrite(im, len, (XPointer)buf);
1014     _XimFlush(im);
1015
1016     _XimUnregisterFilter(ic);
1017     return;
1018 }
1019
1020 Private Bool
1021 _XimResetICCheck(
1022     Xim          im,
1023     INT16        len,
1024     XPointer     data,
1025     XPointer     arg)
1026 {
1027     Xic          ic = (Xic)arg;
1028     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1029     CARD8        major_opcode = *((CARD8 *)data);
1030     CARD8        minor_opcode = *((CARD8 *)data + 1);
1031     XIMID        imid = buf_s[0];
1032     XICID        icid = buf_s[1];
1033
1034     if ((major_opcode == XIM_RESET_IC_REPLY)
1035      && (minor_opcode == 0)
1036      && (imid == im->private.proto.imid)
1037      && (icid == ic->private.proto.icid))
1038         return True;
1039     if ((major_opcode == XIM_ERROR)
1040      && (minor_opcode == 0)
1041      && (buf_s[2] & XIM_IMID_VALID)
1042      && (imid == im->private.proto.imid)
1043      && (buf_s[2] & XIM_ICID_VALID)
1044      && (icid == ic->private.proto.icid))
1045         return True;
1046     return False;
1047 }
1048
1049 Private char *
1050 _XimProtoReset(
1051     XIC          xic,
1052     char *     (*retfunc) (Xim im, Xic ic, XPointer buf) )
1053 {
1054     Xic          ic = (Xic)xic;
1055     Xim          im = (Xim)ic->core.im;
1056     CARD32       buf32[BUFSIZE/4];
1057     CARD8       *buf = (CARD8 *)buf32;
1058     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1059     INT16        len;
1060     CARD32       reply32[BUFSIZE/4];
1061     char        *reply = (char *)reply32;
1062     XPointer     preply;
1063     int          buf_size;
1064     int          ret_code;
1065     char        *commit;
1066
1067     if (!IS_IC_CONNECTED(ic))
1068         return (char *)NULL;
1069
1070     buf_s[0] = im->private.proto.imid;          /* imid */
1071     buf_s[1] = ic->private.proto.icid;          /* icid */
1072
1073     len = sizeof(CARD16)                        /* sizeof imid */
1074         + sizeof(CARD16);                       /* sizeof icid */
1075
1076     _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len);
1077     if (!(_XimWrite(im, len, (XPointer)buf)))
1078         return NULL;
1079     _XimFlush(im);
1080     ic->private.proto.waitCallback = True;
1081     buf_size = BUFSIZE;
1082     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
1083                                         _XimResetICCheck, (XPointer)ic);
1084     if (ret_code == XIM_TRUE) {
1085         preply = reply;
1086     } else if (ret_code == XIM_OVERFLOW) {
1087         if (len < 0) {
1088             preply = reply;
1089         } else {
1090             buf_size = len;
1091             preply = (XPointer)Xmalloc(buf_size);
1092             ret_code = _XimRead(im, &len, preply, buf_size,
1093                                         _XimResetICCheck, (XPointer)ic);
1094             if (ret_code != XIM_TRUE) {
1095                 Xfree(preply);
1096                 ic->private.proto.waitCallback = False;
1097                 return NULL;
1098             }
1099         }
1100     } else {
1101         ic->private.proto.waitCallback = False;
1102         return NULL;
1103     }
1104     ic->private.proto.waitCallback = False;
1105     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
1106     if (*((CARD8 *)preply) == XIM_ERROR) {
1107         _XimProcError(im, 0, (XPointer)&buf_s[3]);
1108         if (reply != preply)
1109             free(preply);
1110         return NULL;
1111     }
1112
1113     commit = retfunc(im, ic, (XPointer)&buf_s[2]);
1114
1115     if (reply != preply)
1116         Xfree(preply);
1117     return commit;
1118 }
1119
1120 Private char *
1121 _XimCommitedMbString(
1122     Xim                  im,
1123     Xic                  ic,
1124     XPointer             buf)
1125 {
1126     CARD16              *buf_s = (CARD16 *)buf;
1127     XimCommitInfo        info;
1128     int                  len;
1129     int                  new_len;
1130     char                *commit;
1131     char                *new_commit = NULL;
1132     char                *str;
1133     Status               status;
1134
1135     len = 0;
1136     for (info = ic->private.proto.commit_info; info; info = info->next)
1137         len += info->string_len;
1138     len += buf_s[0];
1139     if ( len == 0 )
1140         return( NULL );
1141
1142     if (!(commit = (char *)Xmalloc(len + 1)))
1143         goto Error_On_Reset;
1144
1145     str = commit;
1146     for (info = ic->private.proto.commit_info; info; info = info->next) {
1147         (void)memcpy(str, info->string, info->string_len);
1148         str += info->string_len;
1149     }
1150     (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
1151     commit[len] = '\0';
1152
1153     new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status);
1154     if (status != XLookupNone) {
1155         if (!(new_commit = Xmalloc(new_len + 1))) {
1156             Xfree(commit);
1157             goto Error_On_Reset;
1158         }
1159         (void)im->methods->ctstombs((XIM)im, commit, len,
1160                                                 new_commit, new_len, NULL);
1161         new_commit[new_len] = '\0';
1162     }
1163     Xfree(commit);
1164
1165 Error_On_Reset:
1166     _XimFreeCommitInfo( ic );
1167     return new_commit;
1168 }
1169
1170 Private char *
1171 _XimProtoMbReset(
1172     XIC          xic)
1173 {
1174     return _XimProtoReset(xic, _XimCommitedMbString);
1175 }
1176
1177 Private wchar_t *
1178 _XimCommitedWcString(
1179     Xim          im,
1180     Xic          ic,
1181     XPointer     buf)
1182 {
1183     CARD16              *buf_s = (CARD16 *)buf;
1184     XimCommitInfo        info;
1185     int                  len;
1186     int                  new_len;
1187     char                *commit;
1188     wchar_t             *new_commit = (wchar_t *)NULL;
1189     char                *str;
1190     Status               status;
1191
1192     len = 0;
1193     for (info = ic->private.proto.commit_info; info; info = info->next)
1194         len += info->string_len;
1195     len += buf_s[0];
1196     if ( len == 0 )
1197         return( (wchar_t *)NULL );
1198
1199     if (!(commit = (char *)Xmalloc(len + 1)))
1200         goto Error_On_Reset;
1201
1202     str = commit;
1203     for (info = ic->private.proto.commit_info; info; info = info->next) {
1204         (void)memcpy(str, info->string, info->string_len);
1205         str += info->string_len;
1206     }
1207     (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
1208     commit[len] = '\0';
1209
1210     new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status);
1211     if (status != XLookupNone) {
1212         if (!(new_commit =
1213                      (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) {
1214             Xfree(commit);
1215             goto Error_On_Reset;
1216         }
1217         (void)im->methods->ctstowcs((XIM)im, commit, len,
1218                                                 new_commit, new_len, NULL);
1219         new_commit[new_len] = (wchar_t)'\0';
1220     }
1221     Xfree(commit);
1222
1223 Error_On_Reset:
1224     _XimFreeCommitInfo( ic );
1225     return new_commit;
1226 }
1227
1228 Private wchar_t *
1229 _XimProtoWcReset(
1230     XIC          xic)
1231 {
1232     return (wchar_t *) _XimProtoReset(xic,
1233                         (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString);
1234 }
1235
1236 Private char *
1237 _XimCommitedUtf8String(
1238     Xim                  im,
1239     Xic                  ic,
1240     XPointer             buf)
1241 {
1242     CARD16              *buf_s = (CARD16 *)buf;
1243     XimCommitInfo        info;
1244     int                  len;
1245     int                  new_len;
1246     char                *commit;
1247     char                *new_commit = NULL;
1248     char                *str;
1249     Status               status;
1250
1251     len = 0;
1252     for (info = ic->private.proto.commit_info; info; info = info->next)
1253         len += info->string_len;
1254     len += buf_s[0];
1255     if ( len == 0 )
1256         return( NULL );
1257
1258     if (!(commit = (char *)Xmalloc(len + 1)))
1259         goto Error_On_Reset;
1260
1261     str = commit;
1262     for (info = ic->private.proto.commit_info; info; info = info->next) {
1263         (void)memcpy(str, info->string, info->string_len);
1264         str += info->string_len;
1265     }
1266     (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
1267     commit[len] = '\0';
1268
1269     new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status);
1270     if (status != XLookupNone) {
1271         if (!(new_commit = Xmalloc(new_len + 1))) {
1272             Xfree(commit);
1273             goto Error_On_Reset;
1274         }
1275         (void)im->methods->ctstoutf8((XIM)im, commit, len,
1276                                                 new_commit, new_len, NULL);
1277         new_commit[new_len] = '\0';
1278     }
1279     Xfree(commit);
1280
1281 Error_On_Reset:
1282     _XimFreeCommitInfo( ic );
1283     return new_commit;
1284 }
1285
1286 Private char *
1287 _XimProtoUtf8Reset(
1288     XIC          xic)
1289 {
1290     return _XimProtoReset(xic, _XimCommitedUtf8String);
1291 }
1292
1293 Private XICMethodsRec ic_methods = {
1294     _XimProtoDestroyIC,         /* destroy */
1295     _XimProtoSetFocus,          /* set_focus */
1296     _XimProtoUnsetFocus,        /* unset_focus */
1297     _XimProtoSetICValues,       /* set_values */
1298     _XimProtoGetICValues,       /* get_values */
1299     _XimProtoMbReset,           /* mb_reset */
1300     _XimProtoWcReset,           /* wc_reset */
1301     _XimProtoUtf8Reset,         /* utf8_reset */
1302     _XimProtoMbLookupString,    /* mb_lookup_string */
1303     _XimProtoWcLookupString,    /* wc_lookup_string */
1304     _XimProtoUtf8LookupString   /* utf8_lookup_string */
1305 };
1306
1307 Private Bool
1308 _XimGetInputStyle(
1309     XIMArg              *arg,
1310     XIMStyle            *input_style)
1311 {
1312     register XIMArg     *p;
1313
1314     for (p = arg; p && p->name; p++) {
1315         if (!(strcmp(p->name, XNInputStyle))) {
1316             *input_style = (XIMStyle)p->value;
1317             return True;
1318         }
1319     }
1320     return False;
1321 }
1322
1323 #ifdef XIM_CONNECTABLE
1324 Private Bool
1325 _XimDelayModeCreateIC(
1326     Xic                  ic,
1327     XIMArg              *values,
1328     XIMResourceList      res,
1329     unsigned int         num)
1330 {
1331     Xim                  im = (Xim)ic->core.im;
1332     XimDefICValues       ic_values;
1333     int                  len;
1334     XIMStyle             input_style;
1335
1336     bzero((char *)&ic_values, sizeof(XimDefICValues));
1337     _XimGetCurrentICValues(ic, &ic_values);
1338     if (!(_XimGetInputStyle(values, &input_style)))
1339         return False;
1340
1341     _XimSetICMode(res, num, input_style);
1342
1343     if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num,
1344                                         values, XIM_CREATEIC, False)) {
1345         return False;
1346     }
1347     _XimSetCurrentICValues(ic, &ic_values);
1348     if (!_XimSetICDefaults(ic, (XPointer)&ic_values,
1349                                         XIM_SETICDEFAULTS, res, num)) {
1350         return False;
1351     }
1352     ic_values.filter_events = KeyPressMask;
1353     _XimSetCurrentICValues(ic, &ic_values);
1354     _XimRegisterFilter(ic);
1355
1356     return True;
1357 }
1358
1359 Public Bool
1360 _XimReconnectModeCreateIC(ic)
1361     Xic                  ic;
1362 {
1363     Xim                  im = (Xim)ic->core.im;
1364     int                  len;
1365     XIMStyle             input_style = ic->core.input_style;
1366     XIMResourceList      res;
1367     unsigned int         num;
1368
1369     num = im->core.ic_num_resources;
1370     len = sizeof(XIMResource) * num;
1371     if (!(res = (XIMResourceList)Xmalloc(len)))
1372         return False;
1373     (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
1374     ic->private.proto.ic_resources     = res;
1375     ic->private.proto.ic_num_resources = num;
1376
1377     _XimSetICMode(res, num, input_style);
1378
1379     ic->core.filter_events = KeyPressMask;
1380
1381     return True;
1382 }
1383 #endif /* XIM_CONNECTABLE */
1384
1385 Public XIC
1386 _XimProtoCreateIC(
1387     XIM                  xim,
1388     XIMArg              *arg)
1389 {
1390     Xim                  im = (Xim)xim;
1391     Xic                  ic;
1392     XimDefICValues       ic_values;
1393     XIMResourceList      res;
1394     unsigned int         num;
1395     XIMStyle             input_style;
1396     INT16                len;
1397     CARD16              *buf_s;
1398     char                *tmp;
1399     CARD32               tmp_buf32[BUFSIZE/4];
1400     char                *tmp_buf = (char *)tmp_buf32;
1401     char                *buf;
1402     int                  buf_size;
1403     char                *data;
1404     int                  data_len;
1405     int                  ret_len;
1406     int                  total;
1407     XIMArg              *arg_ret;
1408     CARD32               reply32[BUFSIZE/4];
1409     char                *reply = (char *)reply32;
1410     XPointer             preply;
1411     int                  ret_code;
1412
1413 #ifdef XIM_CONNECTABLE
1414     if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im))
1415         return (XIC)NULL;
1416 #else
1417     if (!IS_SERVER_CONNECTED(im))
1418         return (XIC)NULL;
1419 #endif /* XIM_CONNECTABLE */
1420
1421     if (!(_XimGetInputStyle(arg, &input_style)))
1422         return (XIC)NULL;
1423
1424     if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL)
1425         return (XIC)NULL;
1426
1427     ic->methods = &ic_methods;
1428     ic->core.im = (XIM)im;
1429     ic->core.input_style = input_style;
1430
1431     num = im->core.ic_num_resources;
1432     len = sizeof(XIMResource) * num;
1433     if (!(res = (XIMResourceList)Xmalloc(len)))
1434         goto ErrorOnCreatingIC;
1435     (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
1436     ic->private.proto.ic_resources     = res;
1437     ic->private.proto.ic_num_resources = num;
1438
1439 #ifdef XIM_CONNECTABLE
1440     if (!_XimSaveICValues(ic, arg))
1441         return False;
1442
1443     if (!IS_SERVER_CONNECTED(im)) {
1444         if (!_XimConnectServer(im)) {
1445             if (_XimDelayModeCreateIC(ic, arg, res, num)) {
1446                 return (XIC)ic;
1447             }
1448             goto ErrorOnCreatingIC;
1449         }
1450     }
1451 #endif /* XIM_CONNECTABLE */
1452
1453     ic->core.filter_events = im->private.proto.forward_event_mask;
1454     ic->private.proto.forward_event_mask =
1455                                 im->private.proto.forward_event_mask;
1456     ic->private.proto.synchronous_event_mask =
1457                                 im->private.proto.synchronous_event_mask;
1458
1459     num = im->private.proto.ic_num_inner_resources;
1460     len = sizeof(XIMResource) * num;
1461     if (!(res = (XIMResourceList)Xmalloc(len)))
1462         goto ErrorOnCreatingIC;
1463     (void)memcpy((char *)res,
1464                          (char *)im->private.proto.ic_inner_resources, len);
1465     ic->private.proto.ic_inner_resources     = res;
1466     ic->private.proto.ic_num_inner_resources = num;
1467
1468     _XimSetICMode(ic->private.proto.ic_resources,
1469                         ic->private.proto.ic_num_resources, input_style);
1470
1471     _XimSetICMode(ic->private.proto.ic_inner_resources,
1472                         ic->private.proto.ic_num_inner_resources, input_style);
1473
1474     _XimGetCurrentICValues(ic, &ic_values);
1475     buf = tmp_buf;
1476     buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
1477     data_len = BUFSIZE - buf_size;
1478     total = 0;
1479     arg_ret = arg;
1480     for (;;) {
1481         data = &buf[buf_size];
1482         if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
1483                 ic->private.proto.ic_num_resources, arg, &arg_ret, data,
1484                 data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) {
1485             goto ErrorOnCreatingIC;
1486         }
1487
1488         total += ret_len;
1489         if (!(arg = arg_ret)) {
1490             break;
1491         }
1492
1493         buf_size += ret_len;
1494         if (buf == tmp_buf) {
1495             if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
1496                 goto ErrorOnCreatingIC;
1497             }
1498             memcpy(tmp, buf, buf_size);
1499             buf = tmp;
1500         } else {
1501             if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
1502                 Xfree(buf);
1503                 goto ErrorOnCreatingIC;
1504             }
1505             buf = tmp;
1506         }
1507     }
1508     _XimSetCurrentICValues(ic, &ic_values);
1509
1510     if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources,
1511                                         ic->private.proto.ic_num_resources)))
1512         goto ErrorOnCreatingIC;
1513
1514     _XimRegisterFilter(ic);
1515
1516     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1517     buf_s[0] = im->private.proto.imid;
1518     buf_s[1] = (INT16)total;
1519
1520     len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
1521     _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
1522     if (!(_XimWrite(im, len, (XPointer)buf))) {
1523         if (buf != tmp_buf)
1524             Xfree(buf);
1525         goto ErrorOnCreatingIC;
1526     }
1527     _XimFlush(im);
1528     if (buf != tmp_buf)
1529         Xfree(buf);
1530     ic->private.proto.waitCallback = True;
1531     buf_size = BUFSIZE;
1532     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
1533                                                  _XimCreateICCheck, 0);
1534     if (ret_code == XIM_TRUE) {
1535         preply = reply;
1536     } else if (ret_code == XIM_OVERFLOW) {
1537         if (len <= 0) {
1538             preply = reply;
1539         } else {
1540             buf_size = (int)len;
1541             preply = (XPointer)Xmalloc(buf_size);
1542             ret_code = _XimRead(im, &len, preply, buf_size,
1543                                                  _XimCreateICCheck, 0);
1544             if (ret_code != XIM_TRUE) {
1545                 Xfree(preply);
1546                 ic->private.proto.waitCallback = False;
1547                 goto ErrorOnCreatingIC;
1548             }
1549         }
1550     } else {
1551         ic->private.proto.waitCallback = False;
1552         goto ErrorOnCreatingIC;
1553     }
1554     ic->private.proto.waitCallback = False;
1555     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
1556     if (*((CARD8 *)preply) == XIM_ERROR) {
1557         _XimProcError(im, 0, (XPointer)&buf_s[3]);
1558         if (reply != preply)
1559             Xfree(preply);
1560         goto ErrorOnCreatingIC;
1561     }
1562
1563     ic->private.proto.icid = buf_s[1];          /* icid */
1564     if (reply != preply)
1565         Xfree(preply);
1566     MARK_IC_CONNECTED(ic);
1567     return (XIC)ic;
1568
1569 ErrorOnCreatingIC:
1570     _XimUnregisterFilter(ic);
1571     if (ic->private.proto.ic_resources)
1572         Xfree(ic->private.proto.ic_resources);
1573     if (ic->private.proto.ic_inner_resources)
1574         Xfree(ic->private.proto.ic_inner_resources);
1575     Xfree(ic);
1576     return (XIC)NULL;
1577 }