c047715f606268353f1ea8ba8d14ef31387defab
[platform/upstream/libX11.git] / modules / im / ximcp / imRmAttr.c
1 /******************************************************************
2
3            Copyright 1992, 1993, 1994 by FUJITSU LIMITED
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and
8 that both that copyright notice and this permission notice appear
9 in supporting documentation, and that the name of FUJITSU LIMITED
10 not be used in advertising or publicity pertaining to distribution
11 of the software without specific, written prior permission.
12 FUJITSU LIMITED makes no representations about the suitability of
13 this software for any purpose.
14 It is provided "as is" without express or implied warranty.
15
16 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 PERFORMANCE OF THIS SOFTWARE.
23
24   Author: Takashi Fujiwara     FUJITSU LIMITED
25                                fujiwara@a80.tech.yk.fujitsu.co.jp
26
27 ******************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include "Xlibint.h"
33 #include "Xlcint.h"
34 #include "Ximint.h"
35
36
37 Private XIMResourceList
38 _XimGetNestedListSeparator(
39     XIMResourceList      res_list,              /* LISTofIMATTR or IMATTR */
40     unsigned int         res_num)
41 {
42     return  _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList);
43 }
44
45 Private Bool
46 _XimCheckInnerIMAttributes(
47     Xim                  im,
48     XIMArg              *arg,
49     unsigned long        mode)
50 {
51     XIMResourceList      res;
52     int                  check;
53
54     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
55                         im->private.proto.im_num_inner_resources, arg->name)))
56         return False;
57
58     check = _XimCheckIMMode(res, mode);
59     if(check == XIM_CHECK_INVALID)
60         return True;
61     else if(check == XIM_CHECK_ERROR)
62         return False;
63
64     return True;
65 }
66
67 Public char *
68 _XimMakeIMAttrIDList(
69     Xim                  im,
70     XIMResourceList      res_list,
71     unsigned int         res_num,
72     XIMArg              *arg,
73     CARD16              *buf,
74     INT16               *len,
75     unsigned long        mode)
76 {
77     register XIMArg     *p;
78     XIMResourceList      res;
79     int                  check;
80
81     *len = 0;
82     if (!arg)
83         return (char *)NULL;
84
85     for (p = arg; p->name; p++) {
86         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
87             if (_XimCheckInnerIMAttributes(im, p, mode))
88                 continue;
89             return p->name;
90         }
91
92         check = _XimCheckIMMode(res, mode);
93         if (check == XIM_CHECK_INVALID)
94             continue;
95         else if (check == XIM_CHECK_ERROR)
96             return p->name;
97
98         *buf = res->id;
99         *len += sizeof(CARD16);
100          buf++;
101     }
102     return (char *)NULL;
103 }
104
105 Private Bool
106 _XimCheckInnerICAttributes(
107     Xic                  ic,
108     XIMArg              *arg,
109     unsigned long        mode)
110 {
111     XIMResourceList      res;
112     int                  check;
113
114     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
115                         ic->private.proto.ic_num_inner_resources, arg->name)))
116         return False;
117
118     check = _XimCheckICMode(res, mode);
119     if(check == XIM_CHECK_INVALID)
120         return True;
121     else if(check == XIM_CHECK_ERROR)
122         return False;
123
124     return True;
125 }
126
127 Public char *
128 _XimMakeICAttrIDList(
129     Xic                  ic,
130     XIMResourceList      res_list,
131     unsigned int         res_num,
132     XIMArg              *arg,
133     CARD16              *buf,
134     INT16               *len,
135     unsigned long        mode)
136 {
137     register XIMArg     *p;
138     XIMResourceList      res;
139     int                  check;
140     XrmQuark             pre_quark;
141     XrmQuark             sts_quark;
142     char                *name;
143     INT16                new_len;
144
145     *len = 0;
146     if (!arg)
147         return (char *)NULL;
148
149     pre_quark = XrmStringToQuark(XNPreeditAttributes);
150     sts_quark = XrmStringToQuark(XNStatusAttributes);
151
152     for (p = arg; p && p->name; p++) {
153         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
154             if (_XimCheckInnerICAttributes(ic, p, mode))
155                 continue;
156             *len = -1;
157             return p->name;
158         }
159
160         check = _XimCheckICMode(res, mode);
161         if(check == XIM_CHECK_INVALID)
162             continue;
163         else if(check == XIM_CHECK_ERROR) {
164             *len = -1;
165             return p->name;
166         }
167
168         *buf = res->id;
169         *len += sizeof(CARD16);
170         buf++;
171         if (res->resource_size == XimType_NEST) {
172             if (res->xrm_name == pre_quark) {
173                 if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
174                                 (XIMArg *)p->value, buf, &new_len,
175                                 (mode | XIM_PREEDIT_ATTR)))) {
176                     if (new_len < 0) *len = -1;
177                     else *len += new_len;
178                     return name;
179                 }
180                 *len += new_len;
181                 buf = (CARD16 *)((char *)buf + new_len);
182             } else if (res->xrm_name == sts_quark) {
183                 if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
184                                 (XIMArg *)p->value, buf, &new_len,
185                                 (mode | XIM_STATUS_ATTR)))) {
186                     if (new_len < 0) *len = -1;
187                     else *len += new_len;
188                     return name;
189                 }
190                 *len += new_len;
191                 buf = (CARD16 *)((char *)buf + new_len);
192             }
193
194             if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
195                 p++;
196                 if (p) {
197                     *len = -1;
198                     return p->name;
199                 }
200                 else {
201                     return (char *)NULL;
202                 }
203             }
204             *buf = res->id;
205             *len += sizeof(CARD16);
206             buf++;
207         }
208     }
209     return (char *)NULL;
210 }
211
212 Private Bool
213 _XimAttributeToValue(
214     Xic                   ic,
215     XIMResourceList       res,
216     CARD16               *data,
217     INT16                 data_len,
218     XPointer              value,
219     BITMASK32             mode)
220 {
221     switch (res->resource_size) {
222     case XimType_SeparatorOfNestedList:
223     case XimType_NEST:
224         break;
225
226     case XimType_CARD8:
227     case XimType_CARD16:
228     case XimType_CARD32:
229     case XimType_Window:
230     case XimType_XIMHotKeyState:
231         _XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
232         break;
233
234     case XimType_STRING8:
235         {
236             char        *str;
237
238             if (!(value))
239                 return False;
240
241             if (!(str = (char *)Xmalloc(data_len + 1)))
242                 return False;
243
244             (void)memcpy(str, (char *)data, data_len);
245             str[data_len] = '\0';
246
247             *((char **)value) = str;
248             break;
249         }
250
251     case XimType_XIMStyles:
252         {
253             INT16                num = data[0];
254             register CARD32     *style_list = (CARD32 *)&data[2];
255             XIMStyle            *style;
256             XIMStyles           *rep;
257             register int         i;
258             char                *p;
259             int                  alloc_len;
260
261             if (!(value))
262                 return False;
263
264             alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
265             if (!(p = (char *)Xmalloc(alloc_len)))
266                 return False;
267
268             rep   = (XIMStyles *)p;
269             style = (XIMStyle *)(p + sizeof(XIMStyles));
270
271             for (i = 0; i < num; i++)
272                 style[i] = (XIMStyle)style_list[i];
273
274             rep->count_styles = (unsigned short)num;
275             rep->supported_styles = style;
276             *((XIMStyles **)value) = rep;
277             break;
278         }
279
280     case XimType_XRectangle:
281         {
282             XRectangle  *rep;
283
284             if (!(value))
285                 return False;
286
287             if (!(rep = (XRectangle *)Xmalloc(sizeof(XRectangle))))
288                 return False;
289
290             rep->x      = data[0];
291             rep->y      = data[1];
292             rep->width  = data[2];
293             rep->height = data[3];
294             *((XRectangle **)value) = rep;
295             break;
296         }
297
298     case XimType_XPoint:
299         {
300             XPoint      *rep;
301
302             if (!(value))
303                 return False;
304
305             if (!(rep = (XPoint *)Xmalloc(sizeof(XPoint))))
306                 return False;
307
308             rep->x = data[0];
309             rep->y = data[1];
310             *((XPoint **)value) = rep;
311             break;
312         }
313
314     case XimType_XFontSet:
315         {
316             INT16        len = data[0];
317             char        *base_name;
318             XFontSet     rep = (XFontSet)NULL;
319             char        **missing_list = NULL;
320             int          missing_count;
321             char        *def_string;
322
323             if (!(value))
324                 return False;
325             if (!ic)
326                 return False;
327
328             if (!(base_name = (char *)Xmalloc(len + 1)))
329                 return False;
330
331             (void)strncpy(base_name, (char *)&data[1], (int)len);
332             base_name[len] = '\0';
333
334             if (mode & XIM_PREEDIT_ATTR) {
335                 if (!strcmp(base_name, ic->private.proto.preedit_font)) {
336                     rep = ic->core.preedit_attr.fontset;
337                 } else if (!ic->private.proto.preedit_font_length) {
338                     rep = XCreateFontSet(ic->core.im->core.display,
339                                         base_name, &missing_list,
340                                         &missing_count, &def_string);
341                 }
342             } else if (mode & XIM_STATUS_ATTR) {
343                 if (!strcmp(base_name, ic->private.proto.status_font)) {
344                     rep = ic->core.status_attr.fontset;
345                 } else if (!ic->private.proto.status_font_length) {
346                     rep = XCreateFontSet(ic->core.im->core.display,
347                                         base_name, &missing_list,
348                                         &missing_count, &def_string);
349                 }
350             }
351
352             Xfree(base_name);
353             Xfree(missing_list);
354             *((XFontSet *)value) = rep;
355             break;
356         }
357
358     case XimType_XIMHotKeyTriggers:
359         {
360             INT32                        num = *((CARD32 *)data);
361             register CARD32             *key_list = (CARD32 *)&data[2];
362             XIMHotKeyTrigger            *key;
363             XIMHotKeyTriggers           *rep;
364             register int                 i;
365             char                        *p;
366             int                          alloc_len;
367
368             if (!(value))
369                 return False;
370
371             alloc_len = sizeof(XIMHotKeyTriggers)
372                       + sizeof(XIMHotKeyTrigger) * num;
373             if (!(p = (char *)Xmalloc(alloc_len)))
374                 return False;
375
376             rep = (XIMHotKeyTriggers *)p;
377             key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
378
379             for (i = 0; i < num; i++, key_list += 3) {
380                 key[i].keysym        = (KeySym)key_list[0]; /* keysym */
381                 key[i].modifier      = (int)key_list[1];    /* modifier */
382                 key[i].modifier_mask = (int)key_list[2];    /* modifier_mask */
383             }
384
385             rep->num_hot_key = (int)num;
386             rep->key = key;
387             *((XIMHotKeyTriggers **)value) = rep;
388             break;
389         }
390
391     case XimType_XIMStringConversion:
392         {
393             break;
394         }
395
396     default:
397         return False;
398     }
399     return True;
400 }
401
402 Private Bool
403 _XimDecodeInnerIMATTRIBUTE(
404     Xim                  im,
405     XIMArg              *arg)
406 {
407     XIMResourceList      res;
408     XimDefIMValues       im_values;
409
410     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
411                         im->private.proto.im_num_inner_resources, arg->name)))
412         return False;
413
414     _XimGetCurrentIMValues(im, &im_values);
415     return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
416 }
417
418 Public char *
419 _XimDecodeIMATTRIBUTE(
420     Xim                  im,
421     XIMResourceList      res_list,
422     unsigned int         res_num,
423     CARD16              *data,
424     INT16                data_len,
425     XIMArg              *arg,
426     BITMASK32            mode)
427 {
428     register XIMArg     *p;
429     XIMResourceList      res;
430     int                  check;
431     INT16                len;
432     CARD16              *buf;
433     INT16                total;
434     INT16                min_len = sizeof(CARD16)       /* sizeof attributeID */
435                                  + sizeof(INT16);       /* sizeof length */
436
437     for (p = arg; p->name; p++) {
438         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
439             if (_XimDecodeInnerIMATTRIBUTE(im, p))
440                 continue;
441             return p->name;
442         }
443
444         check = _XimCheckIMMode(res, mode);
445         if(check == XIM_CHECK_INVALID)
446             continue;
447         else if(check == XIM_CHECK_ERROR)
448             return p->name;
449
450         total = data_len;
451         buf = data;
452         while (total >= min_len) {
453             if (res->id == buf[0])
454                 break;
455
456             len = buf[1];
457             len += XIM_PAD(len) + min_len;
458             buf = (CARD16 *)((char *)buf + len);
459             total -= len;
460         }
461         if (total < min_len)
462             return p->name;
463
464         if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
465                                    res, &buf[2], buf[1], p->value, mode)))
466             return p->name;
467     }
468     return (char *)NULL;
469 }
470
471 Private Bool
472 _XimDecodeInnerICATTRIBUTE(
473     Xic                  ic,
474     XIMArg              *arg,
475     unsigned long        mode)
476 {
477     XIMResourceList      res;
478     XimDefICValues       ic_values;
479
480     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
481                         ic->private.proto.ic_num_inner_resources, arg->name)))
482         return False;
483
484     _XimGetCurrentICValues(ic, &ic_values);
485     if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
486         return False;
487     _XimSetCurrentICValues(ic, &ic_values);
488     return True;
489 }
490
491 Public char *
492 _XimDecodeICATTRIBUTE(
493     Xic                  ic,
494     XIMResourceList      res_list,
495     unsigned int         res_num,
496     CARD16              *data,
497     INT16                data_len,
498     XIMArg              *arg,
499     BITMASK32            mode)
500 {
501     register XIMArg     *p;
502     XIMResourceList      res;
503     int                  check;
504     INT16                len;
505     CARD16              *buf;
506     INT16                total;
507     char                *name;
508     INT16                min_len = sizeof(CARD16)       /* sizeof attributeID */
509                                  + sizeof(INT16);       /* sizeof length */
510     XrmQuark             pre_quark;
511     XrmQuark             sts_quark;
512
513     if (!arg)
514         return (char *)NULL;
515
516     pre_quark = XrmStringToQuark(XNPreeditAttributes);
517     sts_quark = XrmStringToQuark(XNStatusAttributes);
518
519     for (p = arg; p->name; p++) {
520         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
521             if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
522                 continue;
523             return p->name;
524         }
525
526         check = _XimCheckICMode(res, mode);
527         if (check == XIM_CHECK_INVALID)
528             continue;
529         else if (check == XIM_CHECK_ERROR)
530             return p->name;
531
532         total = data_len;
533         buf = data;
534         while (total >= min_len) {
535             if (res->id == buf[0])
536                 break;
537
538             len = buf[1];
539             len += XIM_PAD(len) + min_len;
540             buf = (CARD16 *)((char *)buf + len);
541             total -= len;
542         }
543         if (total < min_len)
544             return p->name;
545
546         if (res->resource_size == XimType_NEST) {
547             if (res->xrm_name == pre_quark) {
548                 if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
549                         &buf[2], buf[1], (XIMArg *)p->value,
550                         (mode | XIM_PREEDIT_ATTR))))
551                     return name;
552             } else if (res->xrm_name == sts_quark) {
553                 if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
554                         &buf[2], buf[1], (XIMArg *)p->value,
555                         (mode | XIM_STATUS_ATTR))))
556                     return name;
557             }
558         } else {
559             if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
560                                                         p->value, mode)))
561                 return p->name;
562         }
563     }
564     return (char *)NULL;
565 }
566
567 Private Bool
568 _XimValueToAttribute(
569     XIMResourceList      res,
570     XPointer             buf,
571     int                  buf_size,
572     XPointer             value,
573     int                 *len,
574     unsigned long        mode,
575     XPointer             param)
576 {
577     int                  ret_len;
578
579     switch (res->resource_size) {
580     case XimType_SeparatorOfNestedList:
581     case XimType_NEST:
582         *len = 0;
583         break;
584
585     case XimType_CARD8:
586         ret_len = sizeof(CARD8);
587         if (buf_size < ret_len + XIM_PAD(ret_len)) {
588             *len = -1;
589             return False;
590         }
591
592         *((CARD8 *)buf) = (CARD8)(long)value;
593         *len = ret_len;
594         break;
595
596     case XimType_CARD16:
597         ret_len = sizeof(CARD16);
598         if (buf_size < ret_len + XIM_PAD(ret_len)) {
599             *len = -1;
600             return False;
601         }
602
603         *((CARD16 *)buf) = (CARD16)(long)value;
604         *len = ret_len;
605         break;
606
607     case XimType_CARD32:
608     case XimType_Window:
609     case XimType_XIMHotKeyState:
610         ret_len = sizeof(CARD32);
611         if (buf_size < ret_len + XIM_PAD(ret_len)) {
612             *len = -1;
613             return False;
614         }
615
616         *((CARD32 *)buf) = (CARD32)(long)value;
617         *len = ret_len;
618         break;
619
620     case XimType_STRING8:
621         if (!value) {
622             *len = 0;
623             return False;
624         }
625
626         ret_len = strlen((char *)value);
627         if (buf_size < ret_len + XIM_PAD(ret_len)) {
628             *len = -1;
629             return False;
630         }
631
632         (void)memcpy((char *)buf, (char *)value, ret_len);
633         *len = ret_len;
634         break;
635
636     case XimType_XRectangle:
637         {
638             XRectangle  *rect = (XRectangle *)value;
639             CARD16      *buf_s = (CARD16 *)buf;
640
641             if (!rect) {
642                 *len = 0;
643                 return False;
644             }
645
646             ret_len = sizeof(INT16)             /* sizeof X */
647                     + sizeof(INT16)             /* sizeof Y */
648                     + sizeof(CARD16)            /* sizeof width */
649                     + sizeof(CARD16);           /* sizeof height */
650             if (buf_size < ret_len + XIM_PAD(ret_len)) {
651                 *len = -1;
652                 return False;
653             }
654
655             buf_s[0] = (CARD16)rect->x;         /* X */
656             buf_s[1] = (CARD16)rect->y;         /* Y */
657             buf_s[2] = (CARD16)rect->width;     /* width */
658             buf_s[3] = (CARD16)rect->height;    /* heght */
659             *len = ret_len;
660             break;
661         }
662
663     case XimType_XPoint:
664         {
665             XPoint      *point = (XPoint *)value;
666             CARD16      *buf_s = (CARD16 *)buf;
667
668             if (!point) {
669                 *len = 0;
670                 return False;
671             }
672
673             ret_len = sizeof(INT16)             /* sizeof X */
674                     + sizeof(INT16);            /* sizeof Y */
675             if (buf_size < ret_len + XIM_PAD(ret_len)) {
676                 *len = -1;
677                 return False;
678             }
679
680             buf_s[0] = (CARD16)point->x;                /* X */
681             buf_s[1] = (CARD16)point->y;                /* Y */
682             *len = ret_len;
683             break;
684         }
685
686     case XimType_XFontSet:
687         {
688             XFontSet     font = (XFontSet)value;
689             Xic          ic = (Xic)param;
690             char        *base_name = NULL;
691             int          length = 0;
692             CARD16      *buf_s = (CARD16 *)buf;
693
694             if (!font) {
695                 *len = 0;
696                 return False;
697             }
698
699             if (mode & XIM_PREEDIT_ATTR) {
700                 base_name = ic->private.proto.preedit_font;
701                 length    = ic->private.proto.preedit_font_length;
702             } else if (mode & XIM_STATUS_ATTR) {
703                 base_name = ic->private.proto.status_font;
704                 length    = ic->private.proto.status_font_length;
705             }
706
707             if (!base_name) {
708                 *len = 0;
709                 return False;
710             }
711
712             ret_len = sizeof(CARD16)            /* sizeof length of Base name */
713                     + length;                   /* sizeof Base font name list */
714             if (buf_size < ret_len + XIM_PAD(ret_len)) {
715                 *len = -1;
716                 return False;
717             }
718
719             buf_s[0] = (INT16)length;           /* length of Base font name */
720             (void)memcpy((char *)&buf_s[1], base_name, length);
721                                                 /* Base font name list */
722             *len = ret_len;
723             break;
724         }
725
726     case XimType_XIMHotKeyTriggers:
727         {
728             XIMHotKeyTriggers   *hotkey = (XIMHotKeyTriggers *)value;
729             INT32                num;
730             CARD32              *buf_l = (CARD32 *)buf;
731             register CARD32     *key = (CARD32 *)&buf_l[1];
732             register int         i;
733
734             if (!hotkey) {
735                 *len = 0;
736                 return False;
737             }
738             num = (INT32)hotkey->num_hot_key;
739
740             ret_len = sizeof(INT32)             /* sizeof number of key list */
741                    + (sizeof(CARD32)            /* sizeof keysyn */
742                    +  sizeof(CARD32)            /* sizeof modifier */
743                    +  sizeof(CARD32))           /* sizeof modifier_mask */
744                    *  num;                      /* number of key list */
745             if (buf_size < ret_len + XIM_PAD(ret_len)) {
746                 *len = -1;
747                 return False;
748             }
749
750             buf_l[0] = num;             /* number of key list */
751             for (i = 0; i < num; i++, key += 3) {
752                 key[0] = (CARD32)(hotkey->key[i].keysym);
753                                                 /* keysym */
754                 key[1] = (CARD32)(hotkey->key[i].modifier);
755                                                 /* modifier */
756                 key[2] = (CARD32)(hotkey->key[i].modifier_mask);
757                                                 /* modifier_mask */
758             }
759             *len = ret_len;
760             break;
761         }
762
763     case XimType_XIMStringConversion:
764         {
765             *len = 0;
766             break;
767         }
768
769     default:
770         return False;
771     }
772     return True;
773 }
774
775 Private Bool
776 _XimSetInnerIMAttributes(
777     Xim                  im,
778     XPointer             top,
779     XIMArg              *arg,
780     unsigned long        mode)
781 {
782     XIMResourceList      res;
783     int                  check;
784
785     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
786                         im->private.proto.im_num_inner_resources, arg->name)))
787         return False;
788
789     check = _XimCheckIMMode(res, mode);
790     if(check == XIM_CHECK_INVALID)
791         return True;
792     else if(check == XIM_CHECK_ERROR)
793         return False;
794
795     return _XimEncodeLocalIMAttr(res, top, arg->value);
796 }
797
798 Public char *
799 _XimEncodeIMATTRIBUTE(
800     Xim                   im,
801     XIMResourceList       res_list,
802     unsigned int          res_num,
803     XIMArg               *arg,
804     XIMArg              **arg_ret,
805     char                 *buf,
806     int                   size,
807     int                  *ret_len,
808     XPointer              top,
809     unsigned long         mode)
810 {
811     register XIMArg     *p;
812     XIMResourceList      res;
813     int                  check;
814     CARD16              *buf_s;
815     int                  len;
816     int                  min_len = sizeof(CARD16) /* sizeof attribute ID */
817                                  + sizeof(INT16); /* sizeof value length */
818
819     *ret_len = 0;
820     for (p = arg; p->name; p++) {
821         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
822             if (_XimSetInnerIMAttributes(im, top, p, mode))
823                 continue;
824             return p->name;
825         }
826
827         check = _XimCheckIMMode(res, mode);
828         if (check == XIM_CHECK_INVALID)
829             continue;
830         else if (check == XIM_CHECK_ERROR)
831             return p->name;
832
833         if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
834             return p->name;
835
836         buf_s = (CARD16 *)buf;
837         if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
838                                 p->value, &len, mode, (XPointer)NULL)))
839             return p->name;
840
841         if (len == 0) {
842             continue;
843         } else if (len < 0) {
844             *arg_ret = p;
845             return (char *)NULL;
846         }
847
848         buf_s[0] = res->id;                     /* attribute ID */
849         buf_s[1] = len;                         /* value length */
850         XIM_SET_PAD(&buf_s[2], len);            /* pad */
851         len += min_len;
852
853         buf += len;
854         *ret_len += len;
855         size -= len;
856     }
857     *arg_ret = (XIMArg *)NULL;
858     return (char *)NULL;
859 }
860
861 #ifdef XIM_CONNECTABLE
862 Public  Bool
863 _XimEncodeSavedIMATTRIBUTE(
864     Xim                  im,
865     XIMResourceList      res_list,
866     unsigned int         res_num,
867     int                 *idx,
868     char                *buf,
869     int                  size,
870     int                 *ret_len,
871     XPointer             top,
872     unsigned long        mode)
873 {
874     register int         i;
875     int                  num = im->private.proto.num_saved_imvalues;
876     XrmQuark            *quark_list = im->private.proto.saved_imvalues;
877     XIMResourceList      res;
878     XPointer             value;
879     CARD16              *buf_s;
880     int                  len;
881     int                  min_len = sizeof(CARD16) /* sizeof attribute ID */
882                                  + sizeof(INT16); /* sizeof value length */
883
884     if (!im->private.proto.saved_imvalues) {
885         *idx = -1;
886         *ret_len = 0;
887         return True;
888     }
889
890     *ret_len = 0;
891     for (i = *idx; i < num; i++) {
892         if (!(res = _XimGetResourceListRecByQuark(res_list,
893                                                 res_num, quark_list[i])))
894             continue;
895
896         if (!_XimDecodeLocalIMAttr(res, top, value))
897             return False;
898
899         buf_s = (CARD16 *)buf;
900         if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
901                         (size - min_len), value, &len, mode, (XPointer)NULL)))
902             return False;
903
904         if (len == 0) {
905             continue;
906         } else if (len < 0) {
907             *idx = i;
908             return True;
909         }
910
911         buf_s[0] = res->id;                     /* attribute ID */
912         buf_s[1] = len;                         /* value length */
913         XIM_SET_PAD(&buf_s[2], len);            /* pad */
914         len += min_len;
915
916         buf += len;
917         *ret_len += len;
918         size -= len;
919     }
920     *idx = -1;
921     return True;
922 }
923 #endif /* XIM_CONNECTABLE */
924
925 Private Bool
926 _XimEncodeTopValue(
927     Xic                  ic,
928     XIMResourceList      res,
929     XIMArg              *p)
930 {
931     if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
932         ic->core.client_window = (Window)p->value;
933         if (ic->core.focus_window == (Window)0)
934             ic->core.focus_window = ic->core.client_window;
935         _XimRegisterFilter(ic);
936
937     } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
938         if (ic->core.client_window) {
939             _XimUnregisterFilter(ic);
940             ic->core.focus_window = (Window)p->value;
941             _XimRegisterFilter(ic);
942         } else /* client_window not yet */
943             ic->core.focus_window = (Window)p->value;
944     }
945     return True;
946 }
947
948 Private Bool
949 _XimEncodePreeditValue(
950     Xic                  ic,
951     XIMResourceList      res,
952     XIMArg              *p)
953 {
954     if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
955         XStandardColormap       *colormap_ret;
956         int                      count;
957
958         if (!(XGetRGBColormaps(ic->core.im->core.display,
959                                 ic->core.focus_window, &colormap_ret,
960                                 &count, (Atom)p->value)))
961             return False;
962
963         XFree(colormap_ret);
964     } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
965         int               list_ret;
966         XFontStruct     **struct_list;
967         char            **name_list;
968         char             *tmp;
969         int               len;
970         register int      i;
971
972         if (!p->value)
973             return False;
974
975         if (ic->private.proto.preedit_font)
976             Xfree(ic->private.proto.preedit_font);
977
978         list_ret = XFontsOfFontSet((XFontSet)p->value,
979                                                  &struct_list, &name_list);
980         for (i = 0, len = 0; i < list_ret; i++) {
981              len += (strlen(name_list[i]) + sizeof(char));
982         }
983         if (!(tmp = Xmalloc(len + 1))) {
984             ic->private.proto.preedit_font = NULL;
985             return False;
986         }
987
988         tmp[0] = '\0';
989         for (i = 0; i < list_ret; i++) {
990             strcat(tmp, name_list[i]);
991             strcat(tmp, ",");
992         }
993         tmp[len - 1] = 0;
994         ic->private.proto.preedit_font        = tmp;
995         ic->private.proto.preedit_font_length = len - 1;
996     }
997     return True;
998 }
999
1000 Private Bool
1001 _XimEncodeStatusValue(
1002     Xic                  ic,
1003     XIMResourceList      res,
1004     XIMArg              *p)
1005 {
1006     if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
1007         XStandardColormap       *colormap_ret = NULL;
1008         int                      count;
1009
1010         if (!(XGetRGBColormaps(ic->core.im->core.display,
1011                                 ic->core.focus_window, &colormap_ret,
1012                                 &count, (Atom)p->value)))
1013             return False;
1014
1015         XFree(colormap_ret);
1016     } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
1017         int               list_ret;
1018         XFontStruct     **struct_list;
1019         char            **name_list;
1020         char             *tmp;
1021         int               len;
1022         register int      i;
1023
1024         if (!p->value)
1025             return False;
1026
1027         if (ic->private.proto.status_font)
1028             Xfree(ic->private.proto.status_font);
1029
1030         list_ret = XFontsOfFontSet((XFontSet)p->value,
1031                                                  &struct_list, &name_list);
1032         for (i = 0, len = 0; i < list_ret; i++) {
1033              len += (strlen(name_list[i]) + sizeof(char));
1034         }
1035         if (!(tmp = Xmalloc(len+1))) {
1036             ic->private.proto.status_font = NULL;
1037             return False;
1038         }
1039
1040         tmp[0] = '\0';
1041         for(i = 0; i < list_ret; i++) {
1042             strcat(tmp, name_list[i]);
1043             strcat(tmp, ",");
1044         }
1045         tmp[len - 1] = 0;
1046         ic->private.proto.status_font        = tmp;
1047         ic->private.proto.status_font_length = len - 1;
1048     }
1049     return True;
1050 }
1051
1052 Private Bool
1053 _XimSetInnerICAttributes(
1054     Xic                  ic,
1055     XPointer             top,
1056     XIMArg              *arg,
1057     unsigned long        mode)
1058 {
1059     XIMResourceList      res;
1060     int                  check;
1061
1062     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
1063                         ic->private.proto.ic_num_inner_resources, arg->name)))
1064         return False;
1065
1066     check = _XimCheckICMode(res, mode);
1067     if(check == XIM_CHECK_INVALID)
1068         return True;
1069     else if(check == XIM_CHECK_ERROR)
1070         return False;
1071
1072     return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
1073 }
1074
1075 Public char *
1076 _XimEncodeICATTRIBUTE(
1077     Xic                   ic,
1078     XIMResourceList       res_list,
1079     unsigned int          res_num,
1080     XIMArg               *arg,
1081     XIMArg              **arg_ret,
1082     char                 *buf,
1083     int                   size,
1084     int                  *ret_len,
1085     XPointer              top,
1086     BITMASK32            *flag,
1087     unsigned long         mode)
1088 {
1089     register XIMArg     *p;
1090     XIMResourceList      res;
1091     int                  check;
1092     CARD16              *buf_s;
1093     int                  len;
1094     int                  min_len = sizeof(CARD16) /* sizeof attribute ID */
1095                                  + sizeof(INT16); /* sizeof value length */
1096     XrmQuark             pre_quark;
1097     XrmQuark             sts_quark;
1098     char                *name;
1099
1100     pre_quark = XrmStringToQuark(XNPreeditAttributes);
1101     sts_quark = XrmStringToQuark(XNStatusAttributes);
1102
1103     *ret_len = 0;
1104     for (p = arg; p && p->name; p++) {
1105         buf_s = (CARD16 *)buf;
1106         if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
1107             if (_XimSetInnerICAttributes(ic, top, p, mode))
1108                 continue;
1109             return p->name;
1110         }
1111
1112         check = _XimCheckICMode(res, mode);
1113         if (check == XIM_CHECK_INVALID)
1114             continue;
1115         else if (check == XIM_CHECK_ERROR)
1116             return p->name;
1117
1118         if (mode & XIM_PREEDIT_ATTR) {
1119             if (!(_XimEncodePreeditValue(ic, res, p)))
1120                 return p->name;
1121         } else if (mode & XIM_STATUS_ATTR) {
1122             if (!(_XimEncodeStatusValue(ic, res, p)))
1123                 return p->name;
1124         } else {
1125             if (!(_XimEncodeTopValue(ic, res, p)))
1126                 return p->name;
1127         }
1128
1129         if (res->resource_size == XimType_NEST) {
1130             XimDefICValues      *ic_attr = (XimDefICValues *)top;
1131
1132             if (res->xrm_name == pre_quark) {
1133                 XIMArg          *arg_rt;
1134                 if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
1135                                 (XIMArg *)p->value, &arg_rt,
1136                                 (char *)&buf_s[2], (size - min_len),
1137                                  &len, (XPointer)&ic_attr->preedit_attr, flag,
1138                                 (mode | XIM_PREEDIT_ATTR)))) {
1139                     return name;
1140                 }
1141
1142             } else if (res->xrm_name == sts_quark) {
1143                 XIMArg          *arg_rt;
1144                 if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
1145                                 (XIMArg *)p->value,  &arg_rt,
1146                                 (char *)&buf_s[2], (size - min_len),
1147                                  &len, (XPointer)&ic_attr->status_attr, flag,
1148                                 (mode | XIM_STATUS_ATTR)))) {
1149                     return name;
1150                 }
1151             }
1152         } else {
1153 #ifdef EXT_MOVE
1154             if (flag)
1155                 *flag |= _XimExtenArgCheck(p);
1156 #endif
1157             if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
1158                 return p->name;
1159
1160             if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
1161                                 (size - min_len), p->value,
1162                                 &len, mode, (XPointer)ic)))
1163                 return p->name;
1164         }
1165
1166         if (len == 0) {
1167             continue;
1168         } else if (len < 0) {
1169             *arg_ret = p;
1170             return (char *)NULL;
1171         }
1172
1173         buf_s[0] = res->id;                     /* attribute ID */
1174         buf_s[1] = len;                         /* value length */
1175         XIM_SET_PAD(&buf_s[2], len);            /* pad */
1176         len += min_len;
1177
1178         buf += len;
1179         *ret_len += len;
1180         size -= len;
1181     }
1182     *arg_ret = (XIMArg *)NULL;
1183     return (char *)NULL;
1184 }
1185
1186 #ifdef XIM_CONNECTABLE
1187 Private Bool
1188 _XimEncodeSavedPreeditValue(
1189     Xic                   ic,
1190     XIMResourceList       res,
1191     XPointer              value)
1192 {
1193     int                   list_ret;
1194     XFontStruct         **struct_list;
1195     char                **name_list;
1196     char                 *tmp;
1197     int                   len;
1198     register int          i;
1199
1200     if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
1201         if (!value)
1202             return False;
1203
1204         if (ic->private.proto.preedit_font)
1205             Xfree(ic->private.proto.preedit_font);
1206
1207         list_ret = XFontsOfFontSet((XFontSet)value,
1208                                                 &struct_list, &name_list);
1209         for(i = 0, len = 0; i < list_ret; i++) {
1210             len += (strlen(name_list[i]) + sizeof(char));
1211         }
1212         if(!(tmp = Xmalloc(len + 1))) {
1213             ic->private.proto.preedit_font = NULL;
1214             return False;
1215         }
1216
1217         tmp[0] = '\0';
1218         for(i = 0; i < list_ret; i++) {
1219             strcat(tmp, name_list[i]);
1220             strcat(tmp, ",");
1221         }
1222         tmp[len - 1] = 0;
1223         ic->private.proto.preedit_font        = tmp;
1224         ic->private.proto.preedit_font_length = len - 1;
1225     }
1226     return True;
1227 }
1228
1229 Private Bool
1230 _XimEncodeSavedStatusValue(
1231     Xic                   ic,
1232     XIMResourceList       res,
1233     XPointer              value)
1234 {
1235     int                   list_ret;
1236     XFontStruct         **struct_list;
1237     char                **name_list;
1238     char                 *tmp;
1239     int                   len;
1240     register int          i;
1241
1242     if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
1243         if (!value)
1244             return False;
1245
1246         if (ic->private.proto.status_font)
1247             Xfree(ic->private.proto.status_font);
1248
1249         list_ret = XFontsOfFontSet((XFontSet)value,
1250                                                 &struct_list, &name_list);
1251         for(i = 0, len = 0; i < list_ret; i++) {
1252             len += (strlen(name_list[i]) + sizeof(char));
1253         }
1254         if(!(tmp = Xmalloc(len + 1))) {
1255             ic->private.proto.status_font = NULL;
1256             return False;
1257         }
1258
1259         tmp[0] = '\0';
1260         for(i = 0; i < list_ret; i++) {
1261             strcat(tmp, name_list[i]);
1262             strcat(tmp, ",");
1263         }
1264         tmp[len - 1] = 0;
1265         ic->private.proto.status_font        = tmp;
1266         ic->private.proto.status_font_length = len - 1;
1267     }
1268     return True;
1269 }
1270
1271 Public  Bool
1272 _XimEncodeSavedICATTRIBUTE(
1273     Xic                  ic,
1274     XIMResourceList      res_list,
1275     unsigned int         res_num,
1276     int                 *idx,
1277     char                *buf,
1278     int                  size,
1279     int                 *ret_len,
1280     XPointer             top,
1281     unsigned long        mode)
1282 {
1283     int                  i;
1284     int                  num = ic->private.proto.num_saved_icvalues;
1285     XrmQuark            *quark_list = ic->private.proto.saved_icvalues;
1286     XIMResourceList      res;
1287     XPointer             value;
1288     CARD16              *buf_s;
1289     int                  len;
1290     int                  min_len = sizeof(CARD16) /* sizeof attribute ID */
1291                                  + sizeof(INT16); /* sizeof value length */
1292     XrmQuark             pre_quark;
1293     XrmQuark             sts_quark;
1294     XrmQuark             separator;
1295
1296     if (!ic->private.proto.saved_icvalues) {
1297         *idx = -1;
1298         *ret_len = 0;
1299         return True;
1300     }
1301
1302     pre_quark = XrmStringToQuark(XNPreeditAttributes);
1303     sts_quark = XrmStringToQuark(XNStatusAttributes);
1304     separator = XrmStringToQuark(XNSeparatorofNestedList);
1305
1306     *ret_len = 0;
1307     for (i = *idx; i < num; i++) {
1308         if (quark_list[i] == separator) {
1309             *idx = i;
1310             return True;
1311         }
1312
1313         if (!(res = _XimGetResourceListRecByQuark(res_list,
1314                                                 res_num, quark_list[i])))
1315             continue;
1316
1317         if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
1318             return False;
1319
1320         if (mode & XIM_PREEDIT_ATTR) {
1321             if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
1322                 return False;
1323             }
1324         } else if (mode & XIM_STATUS_ATTR) {
1325             if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
1326                 return False;
1327             }
1328         }
1329
1330         buf_s = (CARD16 *)buf;
1331         if (res->resource_size == XimType_NEST) {
1332             XimDefICValues      *ic_attr = (XimDefICValues *)top;
1333
1334             i++;
1335             if (res->xrm_name == pre_quark) {
1336                 if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
1337                                  &i, (char *)&buf_s[2], (size - min_len),
1338                                  &len, (XPointer)&ic_attr->preedit_attr,
1339                                 (mode | XIM_PREEDIT_ATTR))) {
1340                     return False;
1341                 }
1342
1343             } else if (res->xrm_name == sts_quark) {
1344                 if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
1345                                 &i, (char *)&buf_s[2], (size - min_len),
1346                                 &len, (XPointer)&ic_attr->status_attr,
1347                                 (mode | XIM_STATUS_ATTR))) {
1348                     return False;
1349                 }
1350             }
1351         } else {
1352             if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
1353                                 (size - min_len), value,
1354                                 &len, mode, (XPointer)ic))) {
1355                 return False;
1356             }
1357         }
1358
1359         if (len == 0) {
1360             continue;
1361         } else if (len < 0) {
1362             if (quark_list[i] == separator)
1363                 i++;
1364             *idx = i;
1365             return True;
1366         }
1367
1368         buf_s[0] = res->id;                     /* attribute ID */
1369         buf_s[1] = len;                         /* value length */
1370         XIM_SET_PAD(&buf_s[2], len);            /* pad */
1371         len += min_len;
1372
1373         buf += len;
1374         *ret_len += len;
1375         size -= len;
1376     }
1377     *idx = -1;
1378     return True;
1379 }
1380 #endif /* XIM_CONNECTABLE */
1381
1382 Private unsigned int
1383 _XimCountNumberOfAttr(
1384     INT16        total,
1385     CARD16      *attr,
1386     int         *names_len)
1387 {
1388     unsigned int n;
1389     INT16        len;
1390     INT16        min_len = sizeof(CARD16)       /* sizeof attribute ID */
1391                          + sizeof(CARD16)       /* sizeof type of value */
1392                          + sizeof(INT16);       /* sizeof length of attribute */
1393
1394     n = 0;
1395     *names_len = 0;
1396     while (total > min_len) {
1397         len = attr[2];
1398         *names_len += (len + 1);
1399         len += (min_len + XIM_PAD(len + 2));
1400         total -= len;
1401         attr = (CARD16 *)((char *)attr + len);
1402         n++;
1403     }
1404     return n;
1405 }
1406
1407 Public Bool
1408 _XimGetAttributeID(
1409     Xim                   im,
1410     CARD16               *buf)
1411 {
1412     unsigned int          n;
1413     XIMResourceList       res;
1414     char                 *names;
1415     int                   names_len;
1416     XPointer              tmp;
1417     XIMValuesList        *values_list;
1418     char                **values;
1419     int                   values_len;
1420     register int          i;
1421     INT16                 len;
1422     INT16                 min_len = sizeof(CARD16) /* sizeof attribute ID */
1423                                   + sizeof(CARD16) /* sizeof type of value */
1424                                   + sizeof(INT16); /* sizeof length of attr */
1425     /*
1426      * IM attribute ID
1427      */
1428
1429     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
1430         return False;
1431
1432     if (!(res = Xcalloc(n, sizeof(XIMResource))))
1433         return False;
1434
1435     values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
1436     if (!(tmp = Xcalloc(1, values_len))) {
1437         Xfree(res);
1438         return False;
1439     }
1440
1441     values_list = (XIMValuesList *)tmp;
1442     values = (char **)((char *)tmp + sizeof(XIMValuesList));
1443     names = (char *)((char *)values + (sizeof(char **) * n));
1444
1445     values_list->count_values = n;
1446     values_list->supported_values = values;
1447
1448     buf++;
1449     for (i = 0; i < n; i++) {
1450         len = buf[2];
1451         (void)memcpy(names, (char *)&buf[3], len);
1452         values[i] = names;
1453         names[len] = '\0';
1454         res[i].resource_name = names;
1455         res[i].resource_size = buf[1];
1456         res[i].id            = buf[0];
1457         names += (len + 1);
1458         len += (min_len + XIM_PAD(len + 2));
1459         buf = (CARD16 *)((char *)buf + len);
1460     }
1461     _XIMCompileResourceList(res, n);
1462
1463     if (im->core.im_resources)
1464         Xfree(im->core.im_resources);
1465     if (im->core.im_values_list)
1466         Xfree(im->core.im_values_list);
1467     im->core.im_resources     = res;
1468     im->core.im_num_resources = n;
1469     im->core.im_values_list   = values_list;
1470
1471     /*
1472      * IC attribute ID
1473      */
1474
1475     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
1476         return False;
1477
1478     if (!(res = Xcalloc(n, sizeof(XIMResource))))
1479         return False;
1480
1481     values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
1482     if (!(tmp = Xcalloc(1, values_len))) {
1483         Xfree(res);
1484         return False;
1485     }
1486
1487     values_list = (XIMValuesList *)tmp;
1488     values = (char **)((char *)tmp + sizeof(XIMValuesList));
1489     names = (char *)((char *)values + (sizeof(char **) * n));
1490
1491     values_list->count_values = n;
1492     values_list->supported_values = values;
1493
1494     buf += 2;
1495     for (i = 0; i < n; i++) {
1496         len = buf[2];
1497         (void)memcpy(names, (char *)&buf[3], len);
1498         values[i] = names;
1499         names[len] = '\0';
1500         res[i].resource_name = names;
1501         res[i].resource_size = buf[1];
1502         res[i].id            = buf[0];
1503         names += (len + 1);
1504         len += (min_len + XIM_PAD(len + 2));
1505         buf = (CARD16 *)((char *)buf + len);
1506     }
1507     _XIMCompileResourceList(res, n);
1508
1509     if (im->core.ic_resources)
1510         Xfree(im->core.ic_resources);
1511     if (im->core.ic_values_list)
1512         Xfree(im->core.ic_values_list);
1513     im->core.ic_resources     = res;
1514     im->core.ic_num_resources = n;
1515     im->core.ic_values_list   = values_list;
1516
1517     return True;
1518 }