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 */
SetCardAttribute(XICAttribute * value_ret,char * p,XICAttr * ic_attr,int value_length,int need_swap,void ** value_buf)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 
SetFontAttribute(XICAttribute * value_ret,char * p,XICAttr * ic_attr,int value_length,int need_swap,void ** value_buf)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 
SetPointAttribute(XICAttribute * value_ret,char * p,XICAttr * ic_attr,int value_length,int need_swap,void ** value_buf)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 
SetRectAttribute(XICAttribute * value_ret,char * p,XICAttr * ic_attr,int value_length,int need_swap,void ** value_buf)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 */
GetAttrHeader(unsigned char * rec,XICAttribute * list,int need_swap)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 
GetCardAttribute(char * rec,XICAttribute * list,int need_swap)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 
GetFontAttribute(char * rec,XICAttribute * list,int need_swap)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 
GetRectAttribute(char * rec,XICAttribute * list,int need_swap)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     fm = FrameMgrInit (xrectangle_fr, (char *) recp, need_swap);
288     /* put data */
289     FrameMgrPutToken (fm, rect->x);
290     FrameMgrPutToken (fm, rect->y);
291     FrameMgrPutToken (fm, rect->width);
292     FrameMgrPutToken (fm, rect->height);
293     FrameMgrFree (fm);
294 }
295 
GetPointAttribute(char * rec,XICAttribute * list,int need_swap)296 static void GetPointAttribute (char *rec, XICAttribute *list, int need_swap)
297 {
298     FrameMgr fm;
299     extern XimFrameRec xpoint_fr[];
300     XPoint *rect = (XPoint *) list->value;
301     unsigned char *recp = (unsigned char *) rec;
302 
303     GetAttrHeader (recp, list, need_swap);
304     recp += sizeof(CARD16)*2;
305 
306     fm = FrameMgrInit (xpoint_fr, (char *) recp, need_swap);
307     /* put data */
308     FrameMgrPutToken (fm, rect->x);
309     FrameMgrPutToken (fm, rect->y);
310     FrameMgrFree (fm);
311 }
312 
ReadICValue(Xi18n i18n_core,CARD16 icvalue_id,int value_length,void * p,XICAttribute * value_ret,CARD16 * number_ret,int need_swap,void ** value_buf)313 static int ReadICValue (Xi18n i18n_core,
314                         CARD16 icvalue_id,
315                         int value_length,
316                         void *p,
317                         XICAttribute *value_ret,
318                         CARD16 *number_ret,
319                         int need_swap,
320                         void **value_buf)
321 {
322     XICAttr *ic_attr = i18n_core->address.xic_attr;
323     int i;
324 
325     *number_ret = (CARD16) 0;
326 
327     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++, ic_attr++)
328     {
329         if (ic_attr->attribute_id == icvalue_id)
330             break;
331         /*endif*/
332     }
333     /*endfor*/
334     switch (ic_attr->type)
335     {
336     case XimType_NEST:
337         {
338             int total_length = 0;
339             CARD16 attribute_ID;
340             INT16 attribute_length;
341             unsigned char *p1 = (unsigned char *) p;
342             CARD16 ic_len = 0;
343             CARD16 number;
344             FrameMgr fm;
345             extern XimFrameRec attr_head_fr[];
346 
347             while (total_length < value_length)
348             {
349                 fm = FrameMgrInit (attr_head_fr, (char *) p1, need_swap);
350                 /* get data */
351                 FrameMgrGetToken (fm, attribute_ID);
352                 FrameMgrGetToken (fm, attribute_length);
353                 FrameMgrFree (fm);
354                 p1 += sizeof (CARD16)*2;
355                 ReadICValue (i18n_core,
356                              attribute_ID,
357                              attribute_length,
358                              p1,
359                              (value_ret + ic_len),
360                              &number,
361                              need_swap,
362                              value_buf);
363                 ic_len++;
364                 *number_ret += number;
365                 p1 += attribute_length;
366                 p1 += IMPAD (attribute_length);
367                 total_length += (CARD16) sizeof(CARD16)*2
368                                 + (INT16) attribute_length
369                                 + IMPAD (attribute_length);
370             }
371 	    /*endwhile*/
372             return ic_len;
373         }
374 
375     case XimType_CARD8:
376     case XimType_CARD16:
377     case XimType_CARD32:
378     case XimType_Window:
379         SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
380         *number_ret = (CARD16) 1;
381         return *number_ret;
382 
383     case XimType_XFontSet:
384         SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
385         *number_ret = (CARD16) 1;
386         return *number_ret;
387 
388     case XimType_XRectangle:
389         SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
390         *number_ret = (CARD16) 1;
391         return *number_ret;
392 
393     case XimType_XPoint:
394         SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap, value_buf);
395         *number_ret = (CARD16) 1;
396         return *number_ret;
397 
398 #if 0
399     case XimType_XIMHotKeyTriggers:
400         SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
401 	*number_ret = (CARD16) 1;
402 	return *number_ret;
403 #endif
404     }
405     /*endswitch*/
406     return 0;
407 }
408 
CreateNestedList(CARD16 attr_id,XICAttribute * list,int number,int need_swap)409 static XICAttribute *CreateNestedList (CARD16 attr_id,
410                                        XICAttribute *list,
411                                        int number,
412                                        int need_swap)
413 {
414     XICAttribute *nest_list = NULL;
415     register int i;
416     char *values = NULL;
417     char *valuesp;
418     int value_length = 0;
419 
420     if (number == 0)
421         return NULL;
422     /*endif*/
423     for (i = 0;  i < number;  i++)
424     {
425         value_length += sizeof (CARD16)*2;
426         value_length += list[i].value_length;
427         value_length += IMPAD (list[i].value_length);
428     }
429     /*endfor*/
430     if ((values = (char *) malloc (value_length)) == NULL)
431         return NULL;
432     /*endif*/
433     memset (values, 0, value_length);
434 
435     valuesp = values;
436     for (i = 0;  i < number;  i++)
437     {
438         switch (list[i].type)
439         {
440         case XimType_CARD8:
441         case XimType_CARD16:
442         case XimType_CARD32:
443         case XimType_Window:
444             GetCardAttribute (valuesp, &list[i], need_swap);
445             break;
446 
447         case XimType_XFontSet:
448             GetFontAttribute (valuesp, &list[i], need_swap);
449             break;
450 
451         case XimType_XRectangle:
452             GetRectAttribute (valuesp, &list[i], need_swap);
453             break;
454 
455         case XimType_XPoint:
456             GetPointAttribute (valuesp, &list[i], need_swap);
457             break;
458 
459 #if 0
460         case XimType_XIMHotKeyTriggers:
461             GetHotKeyAttribute (valuesp, &list[i], need_swap);
462             break;
463 #endif
464         }
465         /*endswitch*/
466         valuesp += sizeof (CARD16)*2;
467         valuesp += list[i].value_length;
468         valuesp += IMPAD(list[i].value_length);
469     }
470     /*endfor*/
471 
472     nest_list = (XICAttribute *) malloc (sizeof (XICAttribute));
473     if (nest_list == NULL)
474         return NULL;
475     /*endif*/
476     memset (nest_list, 0, sizeof (XICAttribute));
477     nest_list->value = (void *) malloc (value_length);
478     if (nest_list->value == NULL)
479         return NULL;
480     /*endif*/
481     memset (nest_list->value, 0, sizeof (value_length));
482 
483     nest_list->attribute_id = attr_id;
484     nest_list->value_length = value_length;
485     memmove (nest_list->value, values, value_length);
486 
487     XFree (values);
488     return nest_list;
489 }
490 
IsNestedList(Xi18n i18n_core,CARD16 icvalue_id)491 static Bool IsNestedList (Xi18n i18n_core, CARD16 icvalue_id)
492 {
493     XICAttr *ic_attr = i18n_core->address.xic_attr;
494     int i;
495 
496     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++, ic_attr++)
497     {
498         if (ic_attr->attribute_id == icvalue_id)
499         {
500             if (ic_attr->type == XimType_NEST)
501                 return True;
502             /*endif*/
503             return False;
504         }
505         /*endif*/
506     }
507     /*endfor*/
508     return False;
509 }
510 
IsSeparator(Xi18n i18n_core,CARD16 icvalue_id)511 static Bool IsSeparator (Xi18n i18n_core, CARD16 icvalue_id)
512 {
513     return (i18n_core->address.separatorAttr_id == icvalue_id);
514 }
515 
GetICValue(Xi18n i18n_core,XICAttribute * attr_ret,CARD16 * id_list,int list_num)516 static int GetICValue (Xi18n i18n_core,
517                        XICAttribute *attr_ret,
518                        CARD16 *id_list,
519                        int list_num)
520 {
521     XICAttr *xic_attr = i18n_core->address.xic_attr;
522     register int i;
523     register int j;
524     register int n;
525 
526     i =
527     n = 0;
528     if (IsNestedList (i18n_core, id_list[i]))
529     {
530         i++;
531         while (i < list_num  &&  !IsSeparator (i18n_core, id_list[i]))
532         {
533             for (j = 0;  j < i18n_core->address.ic_attr_num;  j++)
534             {
535                 if (xic_attr[j].attribute_id == id_list[i])
536                 {
537                     attr_ret[n].attribute_id = xic_attr[j].attribute_id;
538                     attr_ret[n].name_length = xic_attr[j].length;
539                     attr_ret[n].name = malloc (xic_attr[j].length + 1);
540 		    strcpy(attr_ret[n].name, xic_attr[j].name);
541                     attr_ret[n].type = xic_attr[j].type;
542                     n++;
543                     i++;
544                     break;
545                 }
546                 /*endif*/
547             }
548             /*endfor*/
549         }
550         /*endwhile*/
551     }
552     else
553     {
554         for (j = 0;  j < i18n_core->address.ic_attr_num;  j++)
555         {
556             if (xic_attr[j].attribute_id == id_list[i])
557             {
558                 attr_ret[n].attribute_id = xic_attr[j].attribute_id;
559                 attr_ret[n].name_length = xic_attr[j].length;
560                 attr_ret[n].name = malloc (xic_attr[j].length + 1);
561 		strcpy(attr_ret[n].name, xic_attr[j].name);
562                 attr_ret[n].type = xic_attr[j].type;
563                 n++;
564                 break;
565             }
566             /*endif*/
567         }
568         /*endfor*/
569     }
570     /*endif*/
571     return n;
572 }
573 
SwapAttributes(XICAttribute * list,int number)574 static void SwapAttributes (XICAttribute *list,
575 			   int number){
576     FrameMgr fm;
577     CARD16 c16;
578     extern XimFrameRec short_fr[];
579     CARD32 c32;
580     extern XimFrameRec long_fr[];
581     XPoint xpoint;
582     extern XimFrameRec xpoint_fr[];
583     XRectangle xrect;
584     extern XimFrameRec xrectangle_fr[];
585     int i;
586 
587     for (i = 0; i < number; ++i, ++list) {
588 	if (list->value == NULL)
589 	    continue;
590 	switch (list->type) {
591 	case XimType_CARD16:
592 	    fm = FrameMgrInit (short_fr, (char *)list->value, 1);
593 	    FrameMgrGetToken (fm, c16);
594 	    memmove(list->value, &c16, sizeof(CARD16));
595 	    FrameMgrFree (fm);
596 	    break;
597 	case XimType_CARD32:
598 	case XimType_Window:
599 	    fm = FrameMgrInit (long_fr, (char *)list->value, 1);
600 	    FrameMgrGetToken (fm, c32);
601 	    memmove(list->value, &c32, sizeof(CARD32));
602 	    FrameMgrFree (fm);
603 	    break;
604 	case XimType_XRectangle:
605 	    fm = FrameMgrInit (xrectangle_fr, (char *)list->value, 1);
606 	    FrameMgrGetToken (fm, xrect);
607 	    memmove(list->value, &xrect, sizeof(XRectangle));
608 	    FrameMgrFree (fm);
609 	    break;
610 	case XimType_XPoint:
611 	    fm = FrameMgrInit (xpoint_fr, (char *)list->value, 1);
612 	    FrameMgrGetToken (fm, xpoint);
613 	    memmove(list->value, &xpoint, sizeof(XPoint));
614 	    FrameMgrFree (fm);
615 	    break;
616 	default:
617 	    break;
618 	}
619     }
620 }
621 
622 /* called from CreateICMessageProc and SetICValueMessageProc */
_Xi18nChangeIC(XIMS ims,IMProtocol * call_data,unsigned char * p,int create_flag)623 void _Xi18nChangeIC (XIMS ims,
624                      IMProtocol *call_data,
625                      unsigned char *p,
626                      int create_flag)
627 {
628     Xi18n i18n_core = ims->protocol;
629     FrameMgr fm;
630     FmStatus status;
631     CARD16 byte_length;
632     register int total_size;
633     unsigned char *reply = NULL;
634     register int i;
635     register int attrib_num;
636     XICAttribute *attrib_list;
637     XICAttribute pre_attr[IC_SIZE];
638     XICAttribute sts_attr[IC_SIZE];
639     XICAttribute ic_attr[IC_SIZE];
640     CARD16 preedit_ic_num = 0;
641     CARD16 status_ic_num = 0;
642     CARD16 ic_num = 0;
643     CARD16 connect_id = call_data->any.connect_id;
644     IMChangeICStruct *changeic = (IMChangeICStruct *) &call_data->changeic;
645     extern XimFrameRec create_ic_fr[];
646     extern XimFrameRec create_ic_reply_fr[];
647     extern XimFrameRec set_ic_values_fr[];
648     extern XimFrameRec set_ic_values_reply_fr[];
649     CARD16 input_method_ID;
650 
651     void *value_buf = NULL;
652     void *value_buf_ptr;
653 
654     register int total_value_length = 0;
655 
656     memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE);
657     memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE);
658     memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE);
659 
660     if (create_flag == True)
661     {
662         fm = FrameMgrInit (create_ic_fr,
663                            (char *) p,
664                            _Xi18nNeedSwap (i18n_core, connect_id));
665         /* get data */
666         FrameMgrGetToken (fm, input_method_ID);
667         FrameMgrGetToken (fm, byte_length);
668     }
669     else
670     {
671         fm = FrameMgrInit (set_ic_values_fr,
672                            (char *) p,
673                            _Xi18nNeedSwap (i18n_core, connect_id));
674         /* get data */
675         FrameMgrGetToken (fm, input_method_ID);
676         FrameMgrGetToken (fm, changeic->icid);
677         FrameMgrGetToken (fm, byte_length);
678     }
679     /*endif*/
680     attrib_list = (XICAttribute *) malloc (sizeof (XICAttribute)*IC_SIZE);
681     if (!attrib_list)
682     {
683         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
684         return;
685     }
686     /*endif*/
687     memset (attrib_list, 0, sizeof(XICAttribute)*IC_SIZE);
688 
689     attrib_num = 0;
690     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
691     {
692         void *value;
693         int value_length;
694 
695         FrameMgrGetToken (fm, attrib_list[attrib_num].attribute_id);
696         FrameMgrGetToken (fm, value_length);
697         FrameMgrSetSize (fm, value_length);
698         attrib_list[attrib_num].value_length = value_length;
699         FrameMgrGetToken (fm, value);
700         attrib_list[attrib_num].value = (void *) malloc (value_length + 1);
701         memmove (attrib_list[attrib_num].value, value, value_length);
702 	((char *)attrib_list[attrib_num].value)[value_length] = '\0';
703         attrib_num++;
704         total_value_length += (value_length + 1);
705     }
706     /*endwhile*/
707 
708     value_buf = (void *) malloc (total_value_length);
709     value_buf_ptr = value_buf;
710 
711     if (!value_buf)
712     {
713         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
714         for (i = 0;  i < attrib_num;  i++)
715             XFree (attrib_list[i].value);
716         /*endfor*/
717         XFree (attrib_list);
718         return;
719     }
720     /*endif*/
721 
722     for (i = 0;  i < attrib_num;  i++)
723     {
724         CARD16 number;
725 
726         if (IsNestedList (i18n_core, attrib_list[i].attribute_id))
727         {
728             if (attrib_list[i].attribute_id
729                 == i18n_core->address.preeditAttr_id)
730             {
731                 ReadICValue (i18n_core,
732                              attrib_list[i].attribute_id,
733                              attrib_list[i].value_length,
734                              attrib_list[i].value,
735                              &pre_attr[preedit_ic_num],
736                              &number,
737                              _Xi18nNeedSwap(i18n_core, connect_id),
738                              &value_buf_ptr);
739                 preedit_ic_num += number;
740             }
741             else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id)
742             {
743                 ReadICValue (i18n_core,
744                              attrib_list[i].attribute_id,
745                              attrib_list[i].value_length,
746                              attrib_list[i].value,
747                              &sts_attr[status_ic_num],
748                              &number,
749                              _Xi18nNeedSwap (i18n_core, connect_id),
750                              &value_buf_ptr);
751                 status_ic_num += number;
752             }
753             else
754             {
755                 /* another nested list.. possible? */
756             }
757             /*endif*/
758         }
759         else
760         {
761             ReadICValue (i18n_core,
762                          attrib_list[i].attribute_id,
763                          attrib_list[i].value_length,
764                          attrib_list[i].value,
765                          &ic_attr[ic_num],
766                          &number,
767                          _Xi18nNeedSwap (i18n_core, connect_id),
768                          &value_buf_ptr);
769             ic_num += number;
770         }
771         /*endif*/
772     }
773     /*endfor*/
774     for (i = 0;  i < attrib_num;  i++)
775         XFree (attrib_list[i].value);
776     /*endfor*/
777     XFree (attrib_list);
778 
779     FrameMgrFree (fm);
780 
781     changeic->preedit_attr_num = preedit_ic_num;
782     changeic->status_attr_num = status_ic_num;
783     changeic->ic_attr_num = ic_num;
784     changeic->preedit_attr = pre_attr;
785     changeic->status_attr = sts_attr;
786     changeic->ic_attr = ic_attr;
787 
788     if (i18n_core->address.improto)
789     {
790         if (!(i18n_core->address.improto(ims, call_data))) {
791             XFree (value_buf);
792             return;
793         }
794         /*endif*/
795     }
796 
797     XFree (value_buf);
798 
799     /*endif*/
800     if (create_flag == True)
801     {
802         fm = FrameMgrInit (create_ic_reply_fr,
803                            NULL,
804                            _Xi18nNeedSwap (i18n_core, connect_id));
805     }
806     else
807     {
808         fm = FrameMgrInit (set_ic_values_reply_fr,
809                            NULL,
810                            _Xi18nNeedSwap (i18n_core, connect_id));
811     }
812     /*endif*/
813     total_size = FrameMgrGetTotalSize (fm);
814     reply = (unsigned char *) malloc (total_size);
815 
816     if (!reply)
817     {
818         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
819         return;
820     }
821     /*endif*/
822     memset (reply, 0, total_size);
823     FrameMgrSetBuffer (fm, reply);
824 
825     FrameMgrPutToken (fm, input_method_ID);
826     FrameMgrPutToken (fm, changeic->icid);
827 
828     if (create_flag == True)
829     {
830         _Xi18nSendMessage (ims,
831                            connect_id,
832                            XIM_CREATE_IC_REPLY,
833                            0,
834                            reply,
835                            total_size);
836     }
837     else
838     {
839         _Xi18nSendMessage (ims,
840                            connect_id,
841                            XIM_SET_IC_VALUES_REPLY,
842                            0,
843                            reply,
844                            total_size);
845     }
846     /*endif*/
847     if (create_flag == True)
848     {
849         int on_key_num = i18n_core->address.on_keys.count_keys;
850         int off_key_num = i18n_core->address.off_keys.count_keys;
851 
852         if (on_key_num == 0  &&  off_key_num == 0)
853         {
854             long mask;
855 
856             if (i18n_core->address.imvalue_mask & I18N_FILTERMASK)
857                 mask = i18n_core->address.filterevent_mask;
858             else
859                 mask = DEFAULT_FILTER_MASK;
860             /*endif*/
861             /* static event flow is default */
862             _Xi18nSetEventMask (ims,
863                                 connect_id,
864                                 input_method_ID,
865                                 changeic->icid,
866                                 mask,
867                                 ~mask);
868         }
869         /*endif*/
870     }
871     /*endif*/
872     FrameMgrFree (fm);
873     XFree(reply);
874 }
875 
876 /* called from GetICValueMessageProc */
_Xi18nGetIC(XIMS ims,IMProtocol * call_data,unsigned char * p)877 void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p)
878 {
879     Xi18n i18n_core = ims->protocol;
880     FrameMgr fm;
881     FmStatus status;
882     extern XimFrameRec get_ic_values_fr[];
883     extern XimFrameRec get_ic_values_reply_fr[];
884     CARD16 byte_length;
885     register int total_size;
886     unsigned char *reply = NULL;
887     XICAttribute *preedit_ret = NULL;
888     XICAttribute *status_ret = NULL;
889     register int i;
890     register int number;
891     int iter_count;
892     CARD16 *attrID_list;
893     XICAttribute pre_attr[IC_SIZE];
894     XICAttribute sts_attr[IC_SIZE];
895     XICAttribute ic_attr[IC_SIZE];
896     CARD16 pre_count = 0;
897     CARD16 sts_count = 0;
898     CARD16 ic_count = 0;
899     IMChangeICStruct *getic = (IMChangeICStruct *) &call_data->changeic;
900     CARD16 connect_id = call_data->any.connect_id;
901     CARD16 input_method_ID;
902 
903     memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE);
904     memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE);
905     memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE);
906 
907     fm = FrameMgrInit (get_ic_values_fr,
908                        (char *) p,
909                        _Xi18nNeedSwap (i18n_core, connect_id));
910 
911     /* get data */
912     FrameMgrGetToken (fm, input_method_ID);
913     FrameMgrGetToken (fm, getic->icid);
914     FrameMgrGetToken (fm, byte_length);
915 
916     attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE);  /* bogus */
917     memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE);
918 
919     number = 0;
920     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
921         FrameMgrGetToken (fm, attrID_list[number++]);
922     /*endwhile*/
923     FrameMgrFree (fm);
924 
925     i = 0;
926     while (i < number)
927     {
928         int read_number;
929 
930         if (IsNestedList (i18n_core, attrID_list[i]))
931         {
932             if (attrID_list[i] == i18n_core->address.preeditAttr_id)
933             {
934                 read_number = GetICValue (i18n_core,
935                                           &pre_attr[pre_count],
936                                           &attrID_list[i],
937                                           number);
938                 i += read_number + 1;
939                 pre_count += read_number;
940             }
941             else if (attrID_list[i] == i18n_core->address.statusAttr_id)
942             {
943                 read_number = GetICValue (i18n_core,
944                                           &sts_attr[sts_count],
945                                           &attrID_list[i],
946                                           number);
947                 i += read_number + 1;
948                 sts_count += read_number;
949             }
950             else
951             {
952                 /* another nested list.. possible? */
953             }
954             /*endif*/
955         }
956         else
957         {
958             read_number = GetICValue (i18n_core,
959                                       &ic_attr[ic_count],
960                                       &attrID_list[i],
961                                       number);
962             i += read_number;
963             ic_count += read_number;
964         }
965         /*endif*/
966     }
967     /*endwhile*/
968     getic->preedit_attr_num = pre_count;
969     getic->status_attr_num = sts_count;
970     getic->ic_attr_num = ic_count;
971     getic->preedit_attr = pre_attr;
972     getic->status_attr = sts_attr;
973     getic->ic_attr = ic_attr;
974     if (i18n_core->address.improto)
975     {
976         if (!(i18n_core->address.improto (ims, call_data)))
977             return;
978         /*endif*/
979 	if (_Xi18nNeedSwap (i18n_core, connect_id))
980 	  SwapAttributes(getic->ic_attr, getic->ic_attr_num);
981     }
982     /*endif*/
983     iter_count = getic->ic_attr_num;
984 
985     preedit_ret = CreateNestedList (i18n_core->address.preeditAttr_id,
986                                     getic->preedit_attr,
987                                     getic->preedit_attr_num,
988                                     _Xi18nNeedSwap (i18n_core, connect_id));
989     if (preedit_ret)
990         iter_count++;
991     /*endif*/
992     status_ret = CreateNestedList (i18n_core->address.statusAttr_id,
993                                    getic->status_attr,
994                                    getic->status_attr_num,
995                                    _Xi18nNeedSwap (i18n_core, connect_id));
996     if (status_ret)
997         iter_count++;
998     /*endif*/
999 
1000     fm = FrameMgrInit (get_ic_values_reply_fr,
1001                        NULL,
1002                        _Xi18nNeedSwap (i18n_core, connect_id));
1003 
1004     /* set iteration count for list of ic_attribute */
1005     FrameMgrSetIterCount (fm, iter_count);
1006 
1007     /* set length of BARRAY item in xicattribute_fr */
1008     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1009         FrameMgrSetSize (fm, ic_attr[i].value_length);
1010     /*endfor*/
1011 
1012     if (preedit_ret)
1013         FrameMgrSetSize (fm, preedit_ret->value_length);
1014     /*endif*/
1015     if (status_ret)
1016         FrameMgrSetSize (fm, status_ret->value_length);
1017     /*endif*/
1018     total_size = FrameMgrGetTotalSize (fm);
1019     reply = (unsigned char *) malloc (total_size);
1020     if (reply == NULL)
1021     {
1022         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1023         return;
1024     }
1025     /*endif*/
1026     memset (reply, 0, total_size);
1027     FrameMgrSetBuffer (fm, reply);
1028 
1029     FrameMgrPutToken (fm, input_method_ID);
1030     FrameMgrPutToken (fm, getic->icid);
1031 
1032     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1033     {
1034         FrameMgrPutToken (fm, ic_attr[i].attribute_id);
1035         FrameMgrPutToken (fm, ic_attr[i].value_length);
1036         FrameMgrPutToken (fm, ic_attr[i].value);
1037     }
1038     /*endfor*/
1039     if (preedit_ret)
1040     {
1041         FrameMgrPutToken (fm, preedit_ret->attribute_id);
1042         FrameMgrPutToken (fm, preedit_ret->value_length);
1043         FrameMgrPutToken (fm, preedit_ret->value);
1044     }
1045     /*endif*/
1046     if (status_ret)
1047     {
1048         FrameMgrPutToken (fm, status_ret->attribute_id);
1049         FrameMgrPutToken (fm, status_ret->value_length);
1050         FrameMgrPutToken (fm, status_ret->value);
1051     }
1052     /*endif*/
1053     _Xi18nSendMessage (ims,
1054                        connect_id,
1055                        XIM_GET_IC_VALUES_REPLY,
1056                        0,
1057                        reply,
1058                        total_size);
1059     XFree (reply);
1060     XFree (attrID_list);
1061 
1062     for (i = 0;  i < (int) getic->ic_attr_num;  i++)
1063     {
1064 	if (getic->ic_attr[i].name)
1065 	    XFree (getic->ic_attr[i].name);
1066 	/*endif*/
1067         if (getic->ic_attr[i].value)
1068             XFree (getic->ic_attr[i].value);
1069         /*endif*/
1070     }
1071     /*endfor*/
1072     for (i = 0;  i < (int) getic->preedit_attr_num;  i++)
1073     {
1074 	if (getic->preedit_attr[i].name)
1075 	    XFree (getic->preedit_attr[i].name);
1076 	/*endif*/
1077 	if (getic->preedit_attr[i].value)
1078 	    XFree (getic->preedit_attr[i].value);
1079 	/*endif*/
1080     }
1081     /*endfor*/
1082     for (i = 0;  i < (int) getic->status_attr_num;  i++)
1083     {
1084 	if (getic->status_attr[i].name)
1085 	    XFree (getic->status_attr[i].name);
1086 	/*endif*/
1087 	if (getic->status_attr[i].value)
1088 	    XFree (getic->status_attr[i].value);
1089 	/*endif*/
1090     }
1091     /*endfor*/
1092 
1093     if (preedit_ret)
1094     {
1095         XFree (preedit_ret->value);
1096         XFree (preedit_ret);
1097     }
1098     /*endif*/
1099     if (status_ret)
1100     {
1101         XFree (status_ret->value);
1102         XFree (status_ret);
1103     }
1104     /*endif*/
1105     FrameMgrFree (fm);
1106 }
1107