Tizen 2.1 base
[platform/core/uifw/ise-engine-sunpinyin.git] / wrapper / xim / IMdkit / i18nIc.c
1 /******************************************************************
2  
3          Copyright 1994, 1995 by Sun Microsystems, Inc.
4          Copyright 1993, 1994 by Hewlett-Packard Company
5  
6 Permission to use, copy, modify, distribute, and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of Sun Microsystems, Inc.
11 and Hewlett-Packard not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior permission.
13 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
14 the suitability of this software for any purpose.  It is provided "as is"
15 without express or implied warranty.
16  
17 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
18 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
23 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25  
26   Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
27
28     This version tidied and debugged by Steve Underwood May 1999
29  
30 ******************************************************************/
31
32 #include <X11/Xlib.h>
33 #include "IMdkit.h"
34 #include "Xi18n.h"
35 #include "FrameMgr.h"
36 #include "XimFunc.h"
37
38 #define IC_SIZE 64
39
40 /* Set IC values */
41 static void SetCardAttribute (XICAttribute *value_ret,
42                               char *p,
43                               XICAttr *ic_attr,
44                               int value_length,
45                               int need_swap,
46                               void **value_buf)
47 {
48     FrameMgr fm;
49
50     /*endif*/
51     if (value_length == sizeof (CARD8))
52     {
53         memmove (*value_buf, p, value_length);
54     }
55     else if (value_length == sizeof (CARD16))
56     {
57         INT16 value;
58         extern XimFrameRec short_fr[];
59
60         fm = FrameMgrInit (short_fr, (char *) p, need_swap);
61         /* get data */
62         FrameMgrGetToken (fm, value);
63         FrameMgrFree (fm);
64         memmove (*value_buf, &value, value_length);
65     }
66     else if (value_length == sizeof(CARD32))
67     {
68         INT32 value;
69         extern XimFrameRec long_fr[];
70         
71         fm = FrameMgrInit (long_fr, (char *) p, need_swap);
72         /* get data */
73         FrameMgrGetToken (fm, value);
74         FrameMgrFree (fm);
75         memmove (*value_buf, &value, value_length);
76     }
77     /*endif*/
78     value_ret->attribute_id = ic_attr->attribute_id;
79     value_ret->name = ic_attr->name;
80     value_ret->name_length = ic_attr->length;
81     value_ret->type = ic_attr->type;
82     value_ret->value_length = value_length;
83     value_ret->value = *value_buf;
84  
85     *value_buf += value_length;
86 }
87
88 static void SetFontAttribute (XICAttribute *value_ret,
89                               char *p,
90                               XICAttr *ic_attr,
91                               int value_length,
92                               int need_swap,
93                               void **value_buf)
94 {
95     char *base_name;
96     CARD16 base_length;
97     FrameMgr fm;
98     extern XimFrameRec fontset_fr[];
99
100     fm = FrameMgrInit (fontset_fr, (char *) p, need_swap);
101     /* get data */
102     FrameMgrGetToken (fm, base_length);
103     FrameMgrSetSize (fm, base_length);
104
105     /*endif*/
106     FrameMgrGetToken (fm, base_name);
107     FrameMgrFree(fm);
108     strncpy ((char *) (*value_buf), base_name, base_length);
109     ((char *) *value_buf)[base_length] = (char) 0;
110
111     value_ret->attribute_id = ic_attr->attribute_id;
112     value_ret->name = ic_attr->name;
113     value_ret->name_length = ic_attr->length;
114     value_ret->type = ic_attr->type;
115     value_ret->value_length = value_length;
116     value_ret->value = *value_buf;
117
118     *value_buf += (base_length + 1);
119 }
120
121 static void SetPointAttribute (XICAttribute *value_ret,
122                                char *p,
123                                XICAttr *ic_attr,
124                                int value_length,
125                                int need_swap,
126                                void **value_buf)
127 {
128     XPoint *buf;
129     FrameMgr fm;
130     extern XimFrameRec xpoint_fr[];
131
132     buf = (XPoint *) (*value_buf);
133
134     fm = FrameMgrInit (xpoint_fr, (char *) p, need_swap);
135     /* get data */
136     FrameMgrGetToken (fm, buf->x);
137     FrameMgrGetToken (fm, buf->y);
138     FrameMgrFree (fm);
139
140     value_ret->attribute_id = ic_attr->attribute_id;
141     value_ret->name = ic_attr->name;
142     value_ret->name_length = ic_attr->length;
143     value_ret->type = ic_attr->type;
144     value_ret->value_length = value_length;
145     value_ret->value = (char *) buf;
146
147     *value_buf += value_length;
148 }
149
150 static void SetRectAttribute (XICAttribute *value_ret,
151                               char *p,
152                               XICAttr *ic_attr,
153                               int value_length,
154                               int need_swap,
155                               void **value_buf)
156 {
157     XRectangle *buf;
158     FrameMgr fm;
159     extern XimFrameRec xrectangle_fr[];
160
161     buf = (XRectangle *) (*value_buf);
162  
163     fm = FrameMgrInit (xrectangle_fr, (char *) p, need_swap);
164     /* get data */
165     FrameMgrGetToken (fm, buf->x);
166     FrameMgrGetToken (fm, buf->y);
167     FrameMgrGetToken (fm, buf->width);
168     FrameMgrGetToken (fm, buf->height);
169     FrameMgrFree (fm);
170
171     value_ret->attribute_id = ic_attr->attribute_id;
172     value_ret->name = ic_attr->name;
173     value_ret->name_length = ic_attr->length;
174     value_ret->type = ic_attr->type;
175     value_ret->value_length = value_length;
176     value_ret->value = (char *) buf;
177
178     *value_buf += value_length;
179 }
180
181 #if 0
182 static void SetHotKeyAttribute (XICAttribute *value_ret,
183                                 char *p,
184                                 XICAttr *ic_attr,
185                                 int value_length,
186                                 int need_swap,
187                                 void **value_buf)
188 {
189     INT32 list_number;
190     XIMTriggerKey *hotkeys;
191
192     memmove (&list_number, p, sizeof(INT32)); p += sizeof(INT32);
193
194     hotkeys = (XIMTriggerKey *) (*value_buf);
195
196     memmove (hotkeys, p, list_number*sizeof (XIMTriggerKey));
197
198     value_ret->attribute_id = ic_attr->attribute_id;
199     value_ret->name = ic_attr->name;
200     value_ret->name_length = ic_attr->length;
201     value_ret->type = ic_attr->type;
202     value_ret->value_length = value_length;
203     value_ret->value = (char *) hotkeys;
204
205     *value_buf += value_length;
206 }
207 #endif
208
209 /* get IC values */
210 static void GetAttrHeader (unsigned char *rec,
211                            XICAttribute *list,
212                            int need_swap)
213 {
214     FrameMgr fm;
215     extern XimFrameRec attr_head_fr[];
216
217     fm = FrameMgrInit (attr_head_fr, (char *) rec, need_swap);
218     /* put data */
219     FrameMgrPutToken (fm, list->attribute_id);
220     FrameMgrPutToken (fm, list->value_length);
221     FrameMgrFree (fm);
222 }
223
224 static void GetCardAttribute (char *rec, XICAttribute *list, int need_swap)
225 {
226     FrameMgr fm;
227     unsigned char *recp = (unsigned char *) rec;
228
229     GetAttrHeader (recp, list, need_swap);
230     recp += sizeof (CARD16)*2;
231
232     if (list->value_length == sizeof (CARD8))
233     {
234         memmove (recp, list->value, list->value_length);
235     }
236     else if (list->value_length == sizeof (CARD16))
237     {
238         INT16 *value = (INT16 *) list->value;
239         extern XimFrameRec short_fr[];
240
241         fm = FrameMgrInit (short_fr, (char *) recp, need_swap);
242         /* put data */
243         FrameMgrPutToken (fm, *value);
244         FrameMgrFree (fm);
245     }
246     else if (list->value_length == sizeof (CARD32))
247     {
248         INT32 *value = (INT32 *) list->value;
249         extern XimFrameRec long_fr[];
250
251         fm = FrameMgrInit (long_fr, (char *) recp, need_swap);
252         /* put data */
253         FrameMgrPutToken (fm, *value);
254         FrameMgrFree (fm);
255     }
256     /*endif*/
257 }
258
259 static void GetFontAttribute(char *rec, XICAttribute *list, int need_swap)
260 {
261     FrameMgr fm;
262     extern XimFrameRec fontset_fr[];
263     char *base_name = (char *) list->value;
264     unsigned char *recp = (unsigned char *) rec;
265
266     GetAttrHeader (recp, list, need_swap);
267     recp += sizeof (CARD16)*2;
268
269     fm = FrameMgrInit (fontset_fr, (char *)recp, need_swap);
270     /* put data */
271     FrameMgrSetSize (fm, list->value_length);
272     FrameMgrPutToken (fm, list->value_length);
273     FrameMgrPutToken (fm, base_name);
274     FrameMgrFree (fm);
275 }
276
277 static void GetRectAttribute (char *rec, XICAttribute *list, int need_swap)
278 {
279     FrameMgr fm;
280     extern XimFrameRec xrectangle_fr[];
281     XRectangle *rect = (XRectangle *) list->value;
282     unsigned char *recp = (unsigned char *) rec;
283
284     GetAttrHeader (recp, list, need_swap);
285     recp += sizeof(CARD16)*2;
286
287     if (rect) {
288         fm = FrameMgrInit (xrectangle_fr, (char *) recp, need_swap);
289         /* put data */
290         FrameMgrPutToken (fm, rect->x);
291         FrameMgrPutToken (fm, rect->y);
292         FrameMgrPutToken (fm, rect->width);
293         FrameMgrPutToken (fm, rect->height);
294         FrameMgrFree (fm);
295     }
296 }
297
298 static void GetPointAttribute (char *rec, XICAttribute *list, int need_swap)
299 {
300     FrameMgr fm;
301     extern XimFrameRec xpoint_fr[];
302     XPoint *rect = (XPoint *) list->value;
303     unsigned char *recp = (unsigned char *) rec;
304
305     GetAttrHeader (recp, list, need_swap);
306     recp += sizeof(CARD16)*2;
307
308     fm = FrameMgrInit (xpoint_fr, (char *) recp, need_swap);
309     /* put data */
310     FrameMgrPutToken (fm, rect->x);
311     FrameMgrPutToken (fm, rect->y);
312     FrameMgrFree (fm);
313 }
314
315 static int ReadICValue (Xi18n i18n_core,
316                         CARD16 icvalue_id,
317                         int value_length,
318                         void *p,
319                         XICAttribute *value_ret,
320                         CARD16 *number_ret,
321                         int need_swap,
322                         void **value_buf)
323 {
324     XICAttr *ic_attr = i18n_core->address.xic_attr;
325     int i;
326
327     *number_ret = (CARD16) 0;
328
329     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++, ic_attr++)
330     {
331         if (ic_attr->attribute_id == icvalue_id)
332             break;
333         /*endif*/
334     }
335     /*endfor*/
336     switch (ic_attr->type)
337     {
338     case XimType_NEST:
339         {
340             int total_length = 0;
341             CARD16 attribute_ID;
342             INT16 attribute_length;
343             unsigned char *p1 = (unsigned char *) p;
344             CARD16 ic_len = 0;
345             CARD16 number;
346             FrameMgr fm;
347             extern XimFrameRec attr_head_fr[];
348
349             while (total_length < value_length)
350             {
351                 fm = FrameMgrInit (attr_head_fr, (char *) p1, need_swap);
352                 /* get data */
353                 FrameMgrGetToken (fm, attribute_ID);
354                 FrameMgrGetToken (fm, attribute_length);
355                 FrameMgrFree (fm);
356                 p1 += sizeof (CARD16)*2;
357                 ReadICValue (i18n_core,
358                              attribute_ID,
359                              attribute_length,
360                              p1,
361                              (value_ret + ic_len),
362                              &number,
363                              need_swap,
364                              value_buf);
365                 ic_len++;
366                 *number_ret += number;
367                 p1 += attribute_length;
368                 p1 += IMPAD (attribute_length);
369                 total_length += (CARD16) sizeof(CARD16)*2
370                                 + (INT16) attribute_length
371                                 + IMPAD (attribute_length);
372             }
373             /*endwhile*/
374             return ic_len;
375         }
376
377     case XimType_CARD8:
378     case XimType_CARD16:
379     case XimType_CARD32:
380     case XimType_Window:
381         SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
382         *number_ret = (CARD16) 1;
383         return *number_ret;
384
385     case XimType_XFontSet:
386         SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
387         *number_ret = (CARD16) 1;
388         return *number_ret;
389
390     case XimType_XRectangle:
391         SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
392         *number_ret = (CARD16) 1;
393         return *number_ret;
394
395     case XimType_XPoint:
396         SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap, value_buf);
397         *number_ret = (CARD16) 1;
398         return *number_ret;
399
400 #if 0
401     case XimType_XIMHotKeyTriggers:
402         SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
403         *number_ret = (CARD16) 1;
404         return *number_ret;
405 #endif
406     }
407     /*endswitch*/
408     return 0;
409 }
410
411 static XICAttribute *CreateNestedList (CARD16 attr_id,
412                                        XICAttribute *list,
413                                        int number,
414                                        int need_swap)
415 {
416     XICAttribute *nest_list = NULL;
417     register int i;
418     char *values = NULL;
419     char *valuesp;
420     int value_length = 0;
421
422     if (number == 0)
423         return NULL;
424     /*endif*/
425     for (i = 0;  i < number;  i++)
426     {
427         value_length += sizeof (CARD16)*2;
428         value_length += list[i].value_length;
429         value_length += IMPAD (list[i].value_length);
430     }
431     /*endfor*/
432     if ((values = (char *) malloc (value_length)) == NULL)
433         return NULL;
434     /*endif*/
435     memset (values, 0, value_length);
436
437     valuesp = values;
438     for (i = 0;  i < number;  i++)
439     {
440         switch (list[i].type)
441         {
442         case XimType_CARD8:
443         case XimType_CARD16:
444         case XimType_CARD32:
445         case XimType_Window:
446             GetCardAttribute (valuesp, &list[i], need_swap);
447             break;
448
449         case XimType_XFontSet:
450             GetFontAttribute (valuesp, &list[i], need_swap);
451             break;
452
453         case XimType_XRectangle:
454             GetRectAttribute (valuesp, &list[i], need_swap);
455             break;
456
457         case XimType_XPoint:
458             GetPointAttribute (valuesp, &list[i], need_swap);
459             break;
460
461 #if 0
462         case XimType_XIMHotKeyTriggers:
463             GetHotKeyAttribute (valuesp, &list[i], need_swap);
464             break;
465 #endif
466         }
467         /*endswitch*/
468         valuesp += sizeof (CARD16)*2;
469         valuesp += list[i].value_length;
470         valuesp += IMPAD(list[i].value_length);
471     }
472     /*endfor*/
473     
474     nest_list = (XICAttribute *) malloc (sizeof (XICAttribute));
475     if (nest_list == NULL)
476         return NULL;
477     /*endif*/
478     memset (nest_list, 0, sizeof (XICAttribute));
479     nest_list->value = (void *) malloc (value_length);
480     if (nest_list->value == NULL)
481         return NULL;
482     /*endif*/
483     memset (nest_list->value, 0, sizeof (value_length));
484
485     nest_list->attribute_id = attr_id;
486     nest_list->value_length = value_length;
487     memmove (nest_list->value, values, value_length);
488
489     XFree (values);
490     return nest_list;
491 }
492
493 static Bool IsNestedList (Xi18n i18n_core, CARD16 icvalue_id)
494 {
495     XICAttr *ic_attr = i18n_core->address.xic_attr;
496     int i;
497
498     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++, ic_attr++)
499     {
500         if (ic_attr->attribute_id == icvalue_id)
501         {
502             if (ic_attr->type == XimType_NEST)
503                 return True;
504             /*endif*/
505             return False;
506         }
507         /*endif*/
508     }
509     /*endfor*/
510     return False;
511 }
512
513 static Bool IsSeparator (Xi18n i18n_core, CARD16 icvalue_id)
514 {
515     return (i18n_core->address.separatorAttr_id == icvalue_id);
516 }
517
518 static int GetICValue (Xi18n i18n_core,
519                        XICAttribute *attr_ret,
520                        CARD16 *id_list,
521                        int list_num)
522 {
523     XICAttr *xic_attr = i18n_core->address.xic_attr;
524     register int i;
525     register int j;
526     register int n;
527
528     i =
529     n = 0;
530     if (IsNestedList (i18n_core, id_list[i]))
531     {
532         i++;
533         while (i < list_num  &&  !IsSeparator (i18n_core, id_list[i]))
534         {
535             for (j = 0;  j < i18n_core->address.ic_attr_num;  j++)
536             {
537                 if (xic_attr[j].attribute_id == id_list[i])
538                 {
539                     attr_ret[n].attribute_id = xic_attr[j].attribute_id;
540                     attr_ret[n].name_length = xic_attr[j].length;
541                     attr_ret[n].name = malloc (xic_attr[j].length + 1);
542                     strcpy(attr_ret[n].name, xic_attr[j].name);
543                     attr_ret[n].type = xic_attr[j].type;
544                     n++;
545                     i++;
546                     break;
547                 }
548                 /*endif*/
549             }
550             /*endfor*/
551         }
552         /*endwhile*/
553     }
554     else
555     {
556         for (j = 0;  j < i18n_core->address.ic_attr_num;  j++)
557         {
558             if (xic_attr[j].attribute_id == id_list[i])
559             {
560                 attr_ret[n].attribute_id = xic_attr[j].attribute_id;
561                 attr_ret[n].name_length = xic_attr[j].length;
562                 attr_ret[n].name = malloc (xic_attr[j].length + 1);
563                 strcpy(attr_ret[n].name, xic_attr[j].name);
564                 attr_ret[n].type = xic_attr[j].type;
565                 n++;
566                 break;
567             }
568             /*endif*/
569         }
570         /*endfor*/
571     }
572     /*endif*/
573     return n;
574 }
575
576 static void SwapAttributes (XICAttribute *list,
577                            int number){
578     FrameMgr fm;
579     CARD16 c16;
580     extern XimFrameRec short_fr[];
581     CARD32 c32;
582     extern XimFrameRec long_fr[];
583     XPoint xpoint;
584     extern XimFrameRec xpoint_fr[];
585     XRectangle xrect;
586     extern XimFrameRec xrectangle_fr[];
587     int i;
588
589     for (i = 0; i < number; ++i, ++list) {
590         if (list->value == NULL)
591             continue;
592         switch (list->type) {
593         case XimType_CARD16:
594             fm = FrameMgrInit (short_fr, (char *)list->value, 1);
595             FrameMgrGetToken (fm, c16);
596             memmove(list->value, &c16, sizeof(CARD16));
597             FrameMgrFree (fm);
598             break;
599         case XimType_CARD32:
600         case XimType_Window:
601             fm = FrameMgrInit (long_fr, (char *)list->value, 1);
602             FrameMgrGetToken (fm, c32);
603             memmove(list->value, &c32, sizeof(CARD32));
604             FrameMgrFree (fm);
605             break;
606         case XimType_XRectangle:
607             fm = FrameMgrInit (xrectangle_fr, (char *)list->value, 1);
608             FrameMgrGetToken (fm, xrect);
609             memmove(list->value, &xrect, sizeof(XRectangle));
610             FrameMgrFree (fm);
611             break;
612         case XimType_XPoint:
613             fm = FrameMgrInit (xpoint_fr, (char *)list->value, 1);
614             FrameMgrGetToken (fm, xpoint);
615             memmove(list->value, &xpoint, sizeof(XPoint));
616             FrameMgrFree (fm);
617             break;
618         default:
619             break;
620         }
621     }
622 }
623
624 /* called from CreateICMessageProc and SetICValueMessageProc */
625 void _Xi18nChangeIC (XIMS ims,
626                      IMProtocol *call_data,
627                      unsigned char *p,
628                      int create_flag)
629 {
630     Xi18n i18n_core = ims->protocol;
631     FrameMgr fm;
632     FmStatus status;
633     CARD16 byte_length;
634     register int total_size;
635     unsigned char *reply = NULL;
636     register int i;
637     register int attrib_num;
638     XICAttribute *attrib_list;
639     XICAttribute pre_attr[IC_SIZE];
640     XICAttribute sts_attr[IC_SIZE];
641     XICAttribute ic_attr[IC_SIZE];
642     CARD16 preedit_ic_num = 0;
643     CARD16 status_ic_num = 0;
644     CARD16 ic_num = 0;
645     CARD16 connect_id = call_data->any.connect_id;
646     IMChangeICStruct *changeic = (IMChangeICStruct *) &call_data->changeic;
647     extern XimFrameRec create_ic_fr[];
648     extern XimFrameRec create_ic_reply_fr[];
649     extern XimFrameRec set_ic_values_fr[];
650     extern XimFrameRec set_ic_values_reply_fr[];
651     CARD16 input_method_ID;
652  
653     void *value_buf = NULL;
654     void *value_buf_ptr;
655
656     register int total_value_length = 0;
657
658     memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE);
659     memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE);
660     memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE);
661
662     if (create_flag == True)
663     {
664         fm = FrameMgrInit (create_ic_fr,
665                            (char *) p,
666                            _Xi18nNeedSwap (i18n_core, connect_id));
667         /* get data */
668         FrameMgrGetToken (fm, input_method_ID);
669         FrameMgrGetToken (fm, byte_length);
670     }
671     else
672     {
673         fm = FrameMgrInit (set_ic_values_fr,
674                            (char *) p,
675                            _Xi18nNeedSwap (i18n_core, connect_id));
676         /* get data */
677         FrameMgrGetToken (fm, input_method_ID);
678         FrameMgrGetToken (fm, changeic->icid);
679         FrameMgrGetToken (fm, byte_length);
680     }
681     /*endif*/
682     attrib_list = (XICAttribute *) malloc (sizeof (XICAttribute)*IC_SIZE);
683     if (!attrib_list)
684     {
685         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
686         return;
687     }
688     /*endif*/
689     memset (attrib_list, 0, sizeof(XICAttribute)*IC_SIZE);
690
691     attrib_num = 0;
692     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
693     {
694         void *value;
695         int value_length;
696         
697         FrameMgrGetToken (fm, attrib_list[attrib_num].attribute_id);
698         FrameMgrGetToken (fm, value_length);
699         FrameMgrSetSize (fm, value_length);
700         attrib_list[attrib_num].value_length = value_length;
701         FrameMgrGetToken (fm, value);
702         attrib_list[attrib_num].value = (void *) malloc (value_length + 1);
703         memmove (attrib_list[attrib_num].value, value, value_length);
704         ((char *)attrib_list[attrib_num].value)[value_length] = '\0';
705         attrib_num++;
706         total_value_length += (value_length + 1);
707     }
708     /*endwhile*/
709
710     value_buf = (void *) malloc (total_value_length);
711     value_buf_ptr = value_buf;
712
713     if (!value_buf)
714     {
715         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
716         for (i = 0;  i < attrib_num;  i++)
717             XFree (attrib_list[i].value);
718         /*endfor*/
719         XFree (attrib_list);
720         return;
721     }
722     /*endif*/
723
724     for (i = 0;  i < attrib_num;  i++)
725     {
726         CARD16 number;
727         
728         if (IsNestedList (i18n_core, attrib_list[i].attribute_id))
729         {
730             if (attrib_list[i].attribute_id
731                 == i18n_core->address.preeditAttr_id)
732             {
733                 ReadICValue (i18n_core,
734                              attrib_list[i].attribute_id,
735                              attrib_list[i].value_length,
736                              attrib_list[i].value,
737                              &pre_attr[preedit_ic_num],
738                              &number,
739                              _Xi18nNeedSwap(i18n_core, connect_id),
740                              &value_buf_ptr);
741                 preedit_ic_num += number;
742             }
743             else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id)
744             {
745                 ReadICValue (i18n_core,
746                              attrib_list[i].attribute_id,
747                              attrib_list[i].value_length,
748                              attrib_list[i].value,
749                              &sts_attr[status_ic_num],
750                              &number,
751                              _Xi18nNeedSwap (i18n_core, connect_id),
752                              &value_buf_ptr);
753                 status_ic_num += number;
754             }
755             else
756             {
757                 /* another nested list.. possible? */
758             }
759             /*endif*/
760         }
761         else
762         {
763             ReadICValue (i18n_core,
764                          attrib_list[i].attribute_id,
765                          attrib_list[i].value_length,
766                          attrib_list[i].value,
767                          &ic_attr[ic_num],
768                          &number,
769                          _Xi18nNeedSwap (i18n_core, connect_id),
770                          &value_buf_ptr);
771             ic_num += number;
772         }
773         /*endif*/
774     }
775     /*endfor*/
776     for (i = 0;  i < attrib_num;  i++)
777         XFree (attrib_list[i].value);
778     /*endfor*/
779     XFree (attrib_list);
780
781     FrameMgrFree (fm);
782
783     changeic->preedit_attr_num = preedit_ic_num;
784     changeic->status_attr_num = status_ic_num;
785     changeic->ic_attr_num = ic_num;
786     changeic->preedit_attr = pre_attr;
787     changeic->status_attr = sts_attr;
788     changeic->ic_attr = ic_attr;
789
790     if (i18n_core->address.improto)
791     {
792         if (!(i18n_core->address.improto(ims, call_data))) {
793             XFree (value_buf);
794             return;
795         }
796         /*endif*/
797     }
798
799     XFree (value_buf);
800
801     /*endif*/
802     if (create_flag == True)
803     {
804         fm = FrameMgrInit (create_ic_reply_fr,
805                            NULL,
806                            _Xi18nNeedSwap (i18n_core, connect_id));
807     }
808     else
809     {
810         fm = FrameMgrInit (set_ic_values_reply_fr,
811                            NULL,
812                            _Xi18nNeedSwap (i18n_core, connect_id));
813     }
814     /*endif*/
815     total_size = FrameMgrGetTotalSize (fm);
816     reply = (unsigned char *) malloc (total_size);
817     
818     if (!reply)
819     {
820         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
821         return;
822     }
823     /*endif*/
824     memset (reply, 0, total_size);
825     FrameMgrSetBuffer (fm, reply);
826
827     FrameMgrPutToken (fm, input_method_ID);
828     FrameMgrPutToken (fm, changeic->icid);
829
830     if (create_flag == True)
831     {
832         _Xi18nSendMessage (ims,
833                            connect_id,
834                            XIM_CREATE_IC_REPLY,
835                            0,
836                            reply,
837                            total_size);
838     }
839     else
840     {
841         _Xi18nSendMessage (ims,
842                            connect_id,
843                            XIM_SET_IC_VALUES_REPLY,
844                            0,
845                            reply,
846                            total_size);
847     }
848     /*endif*/
849     if (create_flag == True)
850     {
851         int on_key_num = i18n_core->address.on_keys.count_keys;
852         int off_key_num = i18n_core->address.off_keys.count_keys;
853
854         if (on_key_num == 0  &&  off_key_num == 0)
855         {
856             long mask;
857
858             if (i18n_core->address.imvalue_mask & I18N_FILTERMASK)
859                 mask = i18n_core->address.filterevent_mask;
860             else
861                 mask = DEFAULT_FILTER_MASK;
862             /*endif*/
863             /* static event flow is default */
864             _Xi18nSetEventMask (ims,
865                                 connect_id,
866                                 input_method_ID,
867                                 changeic->icid,
868                                 mask,
869                                 ~mask);
870         }
871         /*endif*/
872     }
873     /*endif*/
874     FrameMgrFree (fm);
875     XFree(reply);
876 }
877
878 /* called from GetICValueMessageProc */
879 void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p)
880 {
881     Xi18n i18n_core = ims->protocol;
882     FrameMgr fm;
883     FmStatus status;
884     extern XimFrameRec get_ic_values_fr[];
885     extern XimFrameRec get_ic_values_reply_fr[];
886     CARD16 byte_length;
887     register int total_size;
888     unsigned char *reply = NULL;
889     XICAttribute *preedit_ret = NULL;
890     XICAttribute *status_ret = NULL;
891     register int i;
892     register int number;
893     int iter_count;
894     CARD16 *attrID_list;
895     XICAttribute pre_attr[IC_SIZE];
896     XICAttribute sts_attr[IC_SIZE];
897     XICAttribute ic_attr[IC_SIZE];
898     CARD16 pre_count = 0;
899     CARD16 sts_count = 0;
900     CARD16 ic_count = 0;
901     IMChangeICStruct *getic = (IMChangeICStruct *) &call_data->changeic;
902     CARD16 connect_id = call_data->any.connect_id;
903     CARD16 input_method_ID;
904
905     memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE);
906     memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE);
907     memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE);
908
909     fm = FrameMgrInit (get_ic_values_fr,
910                        (char *) p,
911                        _Xi18nNeedSwap (i18n_core, connect_id));
912
913     /* get data */
914     FrameMgrGetToken (fm, input_method_ID);
915     FrameMgrGetToken (fm, getic->icid);
916     FrameMgrGetToken (fm, byte_length);
917
918     attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE);  /* bogus */
919     memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE);
920
921     number = 0;
922     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
923         FrameMgrGetToken (fm, attrID_list[number++]);
924     /*endwhile*/
925     FrameMgrFree (fm);
926
927     i = 0;
928     while (i < number)
929     {
930         int read_number;
931         
932         if (IsNestedList (i18n_core, attrID_list[i]))
933         {
934             if (attrID_list[i] == i18n_core->address.preeditAttr_id)
935             {
936                 read_number = GetICValue (i18n_core,
937                                           &pre_attr[pre_count],
938                                           &attrID_list[i],
939                                           number);
940                 i += read_number + 1;
941                 pre_count += read_number;
942             }
943             else if (attrID_list[i] == i18n_core->address.statusAttr_id)
944             {
945                 read_number = GetICValue (i18n_core,
946                                           &sts_attr[sts_count],
947                                           &attrID_list[i],
948                                           number);
949                 i += read_number + 1;
950                 sts_count += read_number;
951             }
952             else
953             {
954                 /* another nested list.. possible? */
955             }
956             /*endif*/
957         }
958         else
959         {
960             read_number = GetICValue (i18n_core,
961                                       &ic_attr[ic_count],
962                                       &attrID_list[i],
963                                       number);
964             i += read_number;
965             ic_count += read_number;
966         }
967         /*endif*/
968     }
969     /*endwhile*/
970     getic->preedit_attr_num = pre_count;
971     getic->status_attr_num = sts_count;
972     getic->ic_attr_num = ic_count;
973     getic->preedit_attr = pre_attr;
974     getic->status_attr = sts_attr;
975     getic->ic_attr = ic_attr;
976     if (i18n_core->address.improto)
977     {
978         if (!(i18n_core->address.improto (ims, call_data)))
979             return;
980         /*endif*/
981         if (_Xi18nNeedSwap (i18n_core, connect_id))
982           SwapAttributes(getic->ic_attr, getic->ic_attr_num);
983     }
984     /*endif*/
985     iter_count = getic->ic_attr_num;
986
987     preedit_ret = CreateNestedList (i18n_core->address.preeditAttr_id,
988                                     getic->preedit_attr,
989                                     getic->preedit_attr_num,
990                                     _Xi18nNeedSwap (i18n_core, connect_id));
991     if (preedit_ret)
992         iter_count++;
993     /*endif*/
994     status_ret = CreateNestedList (i18n_core->address.statusAttr_id,
995                                    getic->status_attr,
996                                    getic->status_attr_num,
997                                    _Xi18nNeedSwap (i18n_core, connect_id));
998     if (status_ret)
999         iter_count++;
1000     /*endif*/
1001
1002     fm = FrameMgrInit (get_ic_values_reply_fr,
1003                        NULL,
1004                        _Xi18nNeedSwap (i18n_core, connect_id));
1005
1006     /* set iteration count for list of ic_attribute */
1007     FrameMgrSetIterCount (fm, iter_count);
1008
1009     /* set length of BARRAY item in xicattribute_fr */
1010     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1011         FrameMgrSetSize (fm, ic_attr[i].value_length);
1012     /*endfor*/
1013     
1014     if (preedit_ret)
1015         FrameMgrSetSize (fm, preedit_ret->value_length);
1016     /*endif*/
1017     if (status_ret)
1018         FrameMgrSetSize (fm, status_ret->value_length);
1019     /*endif*/
1020     total_size = FrameMgrGetTotalSize (fm);
1021     reply = (unsigned char *) malloc (total_size);
1022     if (reply == NULL)
1023     {
1024         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1025         return;
1026     }
1027     /*endif*/
1028     memset (reply, 0, total_size);
1029     FrameMgrSetBuffer (fm, reply);
1030
1031     FrameMgrPutToken (fm, input_method_ID);
1032     FrameMgrPutToken (fm, getic->icid);
1033
1034     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1035     {
1036         FrameMgrPutToken (fm, ic_attr[i].attribute_id);
1037         FrameMgrPutToken (fm, ic_attr[i].value_length);
1038         FrameMgrPutToken (fm, ic_attr[i].value);
1039     }
1040     /*endfor*/
1041     if (preedit_ret)
1042     {
1043         FrameMgrPutToken (fm, preedit_ret->attribute_id);
1044         FrameMgrPutToken (fm, preedit_ret->value_length);
1045         FrameMgrPutToken (fm, preedit_ret->value);
1046     }
1047     /*endif*/
1048     if (status_ret)
1049     {
1050         FrameMgrPutToken (fm, status_ret->attribute_id);
1051         FrameMgrPutToken (fm, status_ret->value_length);
1052         FrameMgrPutToken (fm, status_ret->value);
1053     }
1054     /*endif*/
1055     _Xi18nSendMessage (ims,
1056                        connect_id,
1057                        XIM_GET_IC_VALUES_REPLY,
1058                        0,
1059                        reply,
1060                        total_size);
1061     XFree (reply);
1062     XFree (attrID_list);
1063
1064     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1065     {
1066         if (getic->ic_attr[i].name)
1067             XFree (getic->ic_attr[i].name);
1068         /*endif*/
1069         if (getic->ic_attr[i].value)
1070             XFree (getic->ic_attr[i].value);
1071         /*endif*/
1072     }
1073     /*endfor*/
1074     for (i = 0;  i < (int) getic->preedit_attr_num;  i++)
1075     {
1076         if (getic->preedit_attr[i].name)
1077             XFree (getic->preedit_attr[i].name);
1078         /*endif*/
1079         if (getic->preedit_attr[i].value)
1080             XFree (getic->preedit_attr[i].value);
1081         /*endif*/
1082     }
1083     /*endfor*/
1084     for (i = 0;  i < (int) getic->status_attr_num;  i++)
1085     {
1086         if (getic->status_attr[i].name)
1087             XFree (getic->status_attr[i].name);
1088         /*endif*/
1089         if (getic->status_attr[i].value)
1090             XFree (getic->status_attr[i].value);
1091         /*endif*/
1092     }
1093     /*endfor*/
1094     
1095     if (preedit_ret)
1096     {
1097         XFree (preedit_ret->value);
1098         XFree (preedit_ret);
1099     }
1100     /*endif*/
1101     if (status_ret)
1102     {
1103         XFree (status_ret->value);
1104         XFree (status_ret);
1105     }
1106     /*endif*/
1107     FrameMgrFree (fm);
1108 }