Back to index

im-sdk  12.3.91
i18nIc.c
Go to the documentation of this file.
00001 /******************************************************************
00002  
00003          Copyright 1994, 1995 by Sun Microsystems, Inc.
00004          Copyright 1993, 1994 by Hewlett-Packard Company
00005  
00006 Permission to use, copy, modify, distribute, and sell this software
00007 and its documentation for any purpose is hereby granted without fee,
00008 provided that the above copyright notice appear in all copies and
00009 that both that copyright notice and this permission notice appear
00010 in supporting documentation, and that the name of Sun Microsystems, Inc.
00011 and Hewlett-Packard not be used in advertising or publicity pertaining to
00012 distribution of the software without specific, written prior permission.
00013 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
00014 the suitability of this software for any purpose.  It is provided "as is"
00015 without express or implied warranty.
00016  
00017 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
00018 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
00019 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00020 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
00021 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
00022 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
00023 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
00024 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00025  
00026   Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
00027  
00028 ******************************************************************/
00029 #include <X11/Xlib.h>
00030 #include "X11R6IMProtoData.h"
00031 #include "Xi18n.h"
00032 #include "FrameMgr.h"
00033 #include "XIC_Interface.h"
00034 
00035 #define IC_SIZE 64
00036 
00037 extern int _Xi18nNeedSwap(Xi18n i18n_core, CARD16 connect_id);
00038 extern void _Xi18nSendMessage(XIMS ims, CARD16 connect_id,
00039                   CARD8 major_opcode, CARD8 minor_opcode,
00040                   unsigned char *data, long length);
00041 extern void FreeICAttrValues(
00042         CARD16 preedit_attr_num,
00043         CARD16 status_attr_num,
00044         CARD16 ic_attr_num,
00045         XICAttribute *preedit_attr,
00046         XICAttribute *status_attr,
00047         XICAttribute *ic_attr);
00048 extern void _Xi18nSetEventMask(XIMS ims, CARD16 connect_id,
00049                             CARD16 im_id, CARD16 ic_id,
00050                             CARD32 forward_mask, CARD32 sync_mask);
00051 extern void FreeICAttrNames(
00052         CARD16 preedit_attr_num,
00053         CARD16 status_attr_num,
00054         CARD16 ic_attr_num,
00055         XICAttribute *preedit_attr,
00056         XICAttribute *status_attr,
00057         XICAttribute *ic_attr);
00058 
00059 
00060 /* Set IC values */
00061 static void
00062 SetCardAttribute(XICAttribute *value_ret, char *p, XICAttr *ic_attr,
00063                int value_length, int need_swap)
00064 {
00065     char *buf;
00066     FrameMgr fm;
00067 
00068     if (!(buf = (char *)malloc(value_length)))
00069       return;
00070 
00071     if (value_length == sizeof(CARD8)) {
00072        memmove(buf, p, value_length);
00073     } else if (value_length == sizeof(CARD16)) {
00074        INT16 value;
00075        extern XimFrameRec worddata_fr[];
00076        /* create FrameMgr */
00077        fm = FrameMgrInit(worddata_fr, (char *)p, need_swap);
00078        /* get data */
00079        FrameMgrGetToken(fm, value);
00080        /* free FrameMgr */
00081        FrameMgrFree(fm);
00082        memmove(buf, &value, value_length);
00083     } else if (value_length == sizeof(CARD32)) {
00084        INT32 value;
00085        extern XimFrameRec longdata_fr[];
00086        /* create FrameMgr */
00087        fm = FrameMgrInit(longdata_fr, (char *)p, need_swap);
00088        /* get data */
00089        FrameMgrGetToken(fm, value);
00090        /* free FrameMgr */
00091        FrameMgrFree(fm);
00092        memmove(buf, &value, value_length);
00093     }
00094 
00095     value_ret->attribute_id = ic_attr->attribute_id;
00096     value_ret->name = ic_attr->name;
00097     value_ret->name_length = ic_attr->length;
00098     value_ret->type = ic_attr->type;
00099     value_ret->value_length = value_length;
00100     value_ret->value = buf;
00101 
00102     return;
00103 }
00104 
00105 static void
00106 SetFontAttribute(XICAttribute *value_ret, char *p, XICAttr *ic_attr,
00107                int value_length, int need_swap)
00108 {
00109     char *buf;
00110     char *base_name;
00111     INT16 base_length;
00112     FrameMgr fm;
00113     extern XimFrameRec xfontset_fr[];
00114 
00115     /* create FrameMgr */
00116     fm = FrameMgrInit(xfontset_fr, (char *)p, need_swap);
00117     /* get data */
00118     FrameMgrGetToken(fm, base_length);
00119     FrameMgrSetSize(fm, base_length);
00120     if (!(buf = (char *)malloc(base_length + 1)))
00121        return;
00122     FrameMgrGetToken(fm, base_name);
00123     /* free FrameMgr */
00124     FrameMgrFree(fm);
00125 
00126     strncpy(buf, base_name, base_length);
00127     buf[base_length] = (char)0;
00128 
00129     value_ret->attribute_id = ic_attr->attribute_id;
00130     value_ret->name = ic_attr->name;
00131     value_ret->name_length = ic_attr->length;
00132     value_ret->type = ic_attr->type;
00133     value_ret->value_length = base_length;
00134     value_ret->value = buf;
00135 
00136     return;
00137 }
00138 
00139 static void
00140 SetPointAttribute(XICAttribute *value_ret, char *p, XICAttr *ic_attr,
00141                 int value_length, int need_swap)
00142 {
00143     XPoint *buf;
00144     FrameMgr fm;
00145     extern XimFrameRec xpoint_fr[];
00146 
00147     if (!(buf = (XPoint *)malloc(sizeof(XPoint))))
00148       return;
00149 
00150     /* create FrameMgr */
00151     fm = FrameMgrInit(xpoint_fr, (char *)p, need_swap);
00152     /* get data */
00153     FrameMgrGetToken(fm, buf->x);
00154     FrameMgrGetToken(fm, buf->y);
00155     /* free FrameMgr */
00156     FrameMgrFree(fm);
00157 
00158     memmove(p, &(buf->x), sizeof(INT16)); p += sizeof(INT16);
00159     memmove(p, &(buf->y), sizeof(INT16));
00160 
00161     value_ret->attribute_id = ic_attr->attribute_id;
00162     value_ret->name = ic_attr->name;
00163     value_ret->name_length = ic_attr->length;
00164     value_ret->type = ic_attr->type;
00165     value_ret->value_length = value_length;
00166     value_ret->value = (char *)buf;
00167 
00168     return;
00169 }
00170 
00171 static void
00172 SetRectAttribute(XICAttribute *value_ret, char *p, XICAttr *ic_attr,
00173                 int value_length, int need_swap)
00174 {
00175     XRectangle *buf;
00176     FrameMgr fm;
00177     extern XimFrameRec xrectangle_fr[];
00178 
00179     if (!(buf = (XRectangle *)malloc(sizeof(XRectangle))))
00180       return;
00181 
00182     /* create FrameMgr */
00183     fm = FrameMgrInit(xrectangle_fr, (char *)p, need_swap);
00184     /* get data */
00185     FrameMgrGetToken(fm, buf->x); FrameMgrGetToken(fm, buf->y);
00186     FrameMgrGetToken(fm, buf->width); FrameMgrGetToken(fm, buf->height);
00187     /* free FrameMgr */
00188     FrameMgrFree(fm);
00189 
00190     value_ret->attribute_id = ic_attr->attribute_id;
00191     value_ret->name = ic_attr->name;
00192     value_ret->name_length = ic_attr->length;
00193     value_ret->type = ic_attr->type;
00194     value_ret->value_length = value_length;
00195     value_ret->value = (char *)buf;
00196 
00197     return;
00198 }
00199 
00200 #if 0
00201 static void
00202 SetHotKeyAttribute(XICAttribute *value_ret, char *p, XICAttr *ic_attr,
00203                  int value_length, int need_swap)
00204 {
00205     INT32 list_number;
00206     XIMTriggerKey *hotkeys;
00207 
00208     memmove(&list_number, p, sizeof(INT32)); p += sizeof(INT32);
00209 
00210     hotkeys = (XIMTriggerKey *)malloc(list_number * sizeof(XIMTriggerKey));
00211     if (hotkeys == NULL)
00212       return;
00213     memmove(hotkeys, p, list_number * sizeof(XIMTriggerKey));
00214 
00215     value_ret->attribute_id = ic_attr->attribute_id;
00216     value_ret->name = ic_attr->name;
00217     value_ret->name_length = ic_attr->length;
00218     value_ret->type = ic_attr->type;
00219     value_ret->value_length = value_length;
00220     value_ret->value = (char *)hotkeys;
00221 
00222     return;
00223 }
00224 #endif
00225 
00226 /* get IC values */
00227 static void
00228 GetAttrHeader(unsigned char *rec, XICAttribute *list, int need_swap)
00229 {
00230     FrameMgr fm;
00231     extern XimFrameRec attr_head_fr[];
00232 
00233     /* create FrameMgr of attribute header frame */
00234     fm = FrameMgrInit(attr_head_fr, (char *)rec, need_swap);
00235     /* put data */
00236     FrameMgrPutToken(fm, list->attribute_id);
00237     FrameMgrPutToken(fm, list->value_length);
00238     /* free FrameMgr */
00239     FrameMgrFree(fm);
00240     return;
00241 }
00242 
00243 static void
00244 GetCardAttribute(char *rec, XICAttribute *list, int need_swap)
00245 {
00246     FrameMgr fm;
00247     unsigned char *recp = (unsigned char *)rec;
00248 
00249     GetAttrHeader(recp, list, need_swap);
00250     recp += sizeof(CARD16) * 2;
00251 
00252     if (list->value_length == sizeof(CARD8)) {
00253        memmove(recp, list->value, list->value_length);
00254     } else if (list->value_length == sizeof(CARD16)) {
00255        INT16 *value = (INT16 *)list->value;
00256        extern XimFrameRec worddata_fr[];
00257        /* create FrameMgr */
00258        fm = FrameMgrInit(worddata_fr, (char *)recp, need_swap);
00259        /* put data */
00260        FrameMgrPutToken(fm, *value);
00261        /* free FrameMgr */
00262        FrameMgrFree(fm);
00263     } else if (list->value_length == sizeof(CARD32)) {
00264        INT32 *value = (INT32 *)list->value;
00265        extern XimFrameRec longdata_fr[];
00266        /* create FrameMgr */
00267        fm = FrameMgrInit(longdata_fr, (char *)recp, need_swap);
00268        /* put data */
00269        FrameMgrPutToken(fm, *value);
00270        /* free FrameMgr */
00271        FrameMgrFree(fm);
00272     }
00273     return;
00274 }
00275 
00276 static void
00277 GetFontAttribute(char *rec, XICAttribute *list, int need_swap)
00278 {
00279     FrameMgr fm;
00280     extern XimFrameRec xfontset_fr[];
00281     CARD8 *base_name = (CARD8*)list->value;
00282     unsigned char *recp = (unsigned char *)rec;
00283     INT16 length = list->value_length;
00284 
00285     GetAttrHeader(recp, list, need_swap);
00286     recp += sizeof(CARD16) * 2;
00287 
00288     /* create FrameMgr of fontset frame */
00289     fm = FrameMgrInit(xfontset_fr, (char *)recp, need_swap);
00290     /* put data */
00291     FrameMgrPutToken(fm, length);
00292     FrameMgrSetSize(fm, length);
00293     FrameMgrPutToken(fm, base_name);
00294     /* free FrameMgr */
00295     FrameMgrFree(fm);
00296     return;
00297 }
00298 
00299 static void
00300 GetRectAttribute(char *rec, XICAttribute *list, int need_swap)
00301 {
00302     FrameMgr fm;
00303     extern XimFrameRec xrectangle_fr[];
00304     XRectangle *rect = (XRectangle *)list->value;
00305     unsigned char *recp = (unsigned char *)rec;
00306 
00307     GetAttrHeader(recp, list, need_swap);
00308     recp += sizeof(CARD16) * 2;
00309 
00310     /* create FrameMgr of xrectangle frame */
00311     fm = FrameMgrInit(xrectangle_fr, (char *)recp, need_swap);
00312     /* put data */
00313     FrameMgrPutToken(fm, rect->x); FrameMgrPutToken(fm, rect->y);
00314     FrameMgrPutToken(fm, rect->width); FrameMgrPutToken(fm, rect->height);
00315     /* free FrameMgr */
00316     FrameMgrFree(fm);
00317     return;
00318 }
00319 
00320 static void
00321 GetPointAttribute(char *rec, XICAttribute *list, int need_swap)
00322 {
00323     FrameMgr fm;
00324     extern XimFrameRec xpoint_fr[];
00325     XPoint *rect = (XPoint *)list->value;
00326     unsigned char *recp = (unsigned char *)rec;
00327 
00328     GetAttrHeader(recp, list, need_swap);
00329     recp += sizeof(CARD16) * 2;
00330 
00331     /* create FrameMgr of xpoint frame */
00332     fm = FrameMgrInit(xpoint_fr, (char *)recp, need_swap);
00333     /* put data */
00334     FrameMgrPutToken(fm, rect->x); FrameMgrPutToken(fm, rect->y);
00335     /* free FrameMgr */
00336     FrameMgrFree(fm);
00337     return;
00338 }
00339 
00340 static int
00341 ReadICValue(Xi18n i18n_core, CARD16 icvalue_id, int value_length, void *p,
00342            XICAttribute *value_ret, CARD16 *number_ret,int need_swap)
00343 {
00344     XICAttr *ic_attr = i18n_core->address.xic_attr;
00345     int i;
00346 
00347     *number_ret = (CARD16)0;
00348 
00349     for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) {
00350        if (ic_attr->attribute_id == icvalue_id) {
00351            break;
00352        }
00353     }
00354     switch (ic_attr->type) {
00355       case XimType_NEST:
00356        {
00357            int total_length = 0;
00358            CARD16 attribute_ID;
00359            INT16 attribute_length;
00360            unsigned char *p1 = (unsigned char *) p;
00361            CARD16 ic_len = 0;
00362            CARD16 number;
00363            FrameMgr fm;
00364            extern XimFrameRec attr_head_fr[];
00365 
00366            while (total_length < value_length) {
00367               /* create FrameMgr */
00368               fm = FrameMgrInit(attr_head_fr, (char *)p1, need_swap);
00369               /* get data */
00370               FrameMgrGetToken(fm, attribute_ID);
00371               FrameMgrGetToken(fm, attribute_length);
00372               /* free FrameMgr */
00373               FrameMgrFree(fm);
00374               p1 += sizeof(CARD16) * 2;
00375               ReadICValue(i18n_core,
00376                          attribute_ID, attribute_length,
00377                          p1, (value_ret + ic_len), &number, need_swap);
00378               ic_len++;
00379               *number_ret += number;
00380               p1 += attribute_length;
00381               p1 += IMPAD(attribute_length);
00382               total_length += (CARD16)sizeof(CARD16) * 2
00383                               + (INT16)attribute_length
00384                               + IMPAD(attribute_length);
00385            }
00386            return ic_len;
00387        }
00388       case XimType_CARD8:
00389       case XimType_CARD16:
00390       case XimType_CARD32:
00391       case XimType_Window:
00392        SetCardAttribute(value_ret, p, ic_attr, value_length, need_swap);
00393        *number_ret = (CARD16)1;
00394        return *number_ret;
00395       case XimType_XFontSet:
00396        SetFontAttribute(value_ret, p, ic_attr, value_length, need_swap);
00397        *number_ret = (CARD16)1;
00398        return *number_ret;
00399       case XimType_XRectangle:
00400        SetRectAttribute(value_ret, p, ic_attr, value_length, need_swap);
00401        *number_ret = (CARD16)1;
00402        return *number_ret;
00403       case XimType_XPoint:
00404        SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap);
00405        *number_ret = (CARD16)1;
00406        return *number_ret;
00407 #if 0
00408       case XimType_XIMHotKeyTriggers:
00409        SetHotKeyAttribute(value_ret, p, ic_attr, value_length, need_swap);
00410 #endif
00411       default:
00412        return 0;
00413     }
00414 }
00415 
00416 static int
00417 GetValueLength(int type, char *value) {
00418   int length = 0;
00419   switch (type) {
00420   case XimType_CARD8:
00421     length = sizeof(CARD8);
00422     break;
00423   case XimType_CARD16:
00424     length = sizeof(CARD16);
00425     break;
00426   case XimType_CARD32:
00427   case XimType_Window:
00428     length = sizeof(CARD32);
00429     break;
00430   case XimType_XIMStyles:
00431     length = sizeof(XIMStyles);
00432     break;
00433   case XimType_XRectangle:
00434     length = sizeof(XRectangle);
00435     break;
00436   case XimType_XPoint:
00437     length = sizeof(XPoint);
00438     break;
00439   case XimType_XFontSet:
00440   case XimType_STRING8:
00441     length = strlen(value);
00442     break;
00443   }
00444   return length;
00445 }
00446 
00447 static XICAttribute *
00448 CreateNestedList(CARD16 attr_id, XICAttribute *list,
00449                int number, int need_swap)
00450 {
00451     XICAttribute *nest_list = NULL;
00452     register int i;
00453     char *values = NULL, *valuesp;
00454     int value_length = 0;
00455 
00456     if (number == 0) return NULL;
00457     for (i = 0; i < number; i++) {
00458        value_length += sizeof(CARD16) * 2;
00459        list[i].value_length = GetValueLength(list[i].type,
00460                                          list[i].value);
00461        value_length += list[i].value_length;
00462        value_length += IMPAD(list[i].value_length);
00463     }
00464     if ((values = (char *)malloc(value_length)) == NULL)
00465       return NULL;
00466     memset(values, 0, value_length);
00467 
00468     valuesp = values;
00469     for (i = 0; i < number; i++) {
00470        switch (list[i].type) {
00471          case XimType_CARD8:
00472          case XimType_CARD16:
00473          case XimType_CARD32:
00474          case XimType_Window:
00475            GetCardAttribute(valuesp, &list[i], need_swap);
00476            break;
00477          case XimType_XFontSet:
00478            GetFontAttribute(valuesp, &list[i], need_swap);
00479            break;
00480          case XimType_XRectangle:
00481            GetRectAttribute(valuesp, &list[i], need_swap);
00482            break;
00483          case XimType_XPoint:
00484            GetPointAttribute(valuesp, &list[i], need_swap);
00485            break;
00486 #if 0
00487          case XimType_XIMHotKeyTriggers:
00488            GetHotKeyAttribute(valuesp, &list[i], need_swap);
00489            break;
00490 #endif
00491          default:
00492            break;
00493        }
00494        valuesp += sizeof(CARD16) * 2;
00495        valuesp += list[i].value_length;
00496        valuesp += IMPAD(list[i].value_length);
00497     }
00498 
00499     nest_list = (XICAttribute *)malloc(sizeof(XICAttribute));
00500     if (nest_list == NULL)
00501       return NULL;
00502     memset(nest_list, 0, sizeof(XICAttribute));
00503     nest_list->value = (void *)malloc(value_length);
00504     if (nest_list->value == NULL)
00505       return NULL;
00506     memset(nest_list->value, 0, sizeof(value_length));
00507 
00508     nest_list->attribute_id = attr_id;
00509     nest_list->value_length = value_length;
00510     memmove(nest_list->value, values, value_length);
00511 
00512     XFree(values);
00513     return (nest_list);
00514 }
00515 
00516 static Bool
00517 IsNestedList(Xi18n i18n_core, CARD16 icvalue_id)
00518 {
00519     XICAttr *ic_attr = i18n_core->address.xic_attr;
00520     int i;
00521 
00522     for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) {
00523        if (ic_attr->attribute_id == icvalue_id) {
00524            if (ic_attr->type == XimType_NEST)
00525              return True;
00526            else
00527              return False;
00528        }
00529     }
00530     return False;
00531 }
00532 
00533 static Bool
00534 IsSeparator(Xi18n i18n_core, CARD16 icvalue_id)
00535 {
00536     return (i18n_core->address.separatorAttr_id == icvalue_id);
00537 }
00538 
00539 static void
00540 GetICValue(Xi18n i18n_core, XICAttribute *attr_ret,
00541            CARD16 *id_list, int list_num, int *number_ret)
00542 {
00543     XICAttr *xic_attr = i18n_core->address.xic_attr;
00544     register int i, j, n;
00545 
00546     i = n = 0;
00547     if (IsNestedList(i18n_core, id_list[i])) {
00548        i++;
00549        while (i < list_num && !IsSeparator(i18n_core, id_list[i])) {
00550            for (j = 0; j < i18n_core->address.ic_attr_num; j++) {
00551               if (xic_attr[j].attribute_id == id_list[i]) {
00552                   attr_ret[n].attribute_id = xic_attr[j].attribute_id;
00553                   attr_ret[n].name_length = xic_attr[j].length;
00554                   attr_ret[n].name = malloc(xic_attr[j].length + 1);
00555                   strcpy(attr_ret[n].name, xic_attr[j].name);
00556                   attr_ret[n].type = xic_attr[j].type;
00557                   n++; i++;
00558                   break;
00559               }
00560            }
00561        }
00562     } else {
00563        for (j = 0; j < i18n_core->address.ic_attr_num; j++) {
00564            if (xic_attr[j].attribute_id == id_list[i]) {
00565               attr_ret[n].attribute_id = xic_attr[j].attribute_id;
00566               attr_ret[n].name_length = xic_attr[j].length;
00567               attr_ret[n].name = malloc(xic_attr[j].length + 1);
00568               strcpy(attr_ret[n].name, xic_attr[j].name);
00569               attr_ret[n].type = xic_attr[j].type;
00570               n++;
00571               break;
00572            }
00573        }
00574     }
00575     *number_ret = n;
00576     return;
00577 }
00578 
00579 /* called from CreateICMessageProc and SetICValueMessageProc */
00580 void
00581 _Xi18nChangeIC(XIMS ims, X11R6IMProtocol call_data,
00582               unsigned char *p, int create_flag) {
00583     Xi18n i18n_core = ims->protocol;
00584     FrameMgr fm;
00585     FmStatus status;
00586     CARD16 byte_length;
00587     register int total_size;
00588     unsigned char *reply = NULL;
00589     register int i, attrib_num;
00590     XICAttribute *attrib_list;
00591     XICAttribute pre_attr[IC_SIZE], sts_attr[IC_SIZE], ic_attr[IC_SIZE];
00592     CARD16 preedit_ic_num = 0, status_ic_num = 0, ic_num = 0;
00593     CARD16 connect_id = call_data->any.connect_id;
00594     IMChangeICStruct *changeic =
00595       (IMChangeICStruct*)&call_data->changeic;
00596     extern XimFrameRec create_ic_fr[], create_ic_reply_fr[];
00597     extern XimFrameRec set_ic_values_fr[], set_ic_values_reply_fr[];
00598     CARD16 input_method_ID;
00599 
00600     memset(pre_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00601     memset(sts_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00602     memset(ic_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00603 
00604     /* create FrameMgr */
00605     if (create_flag == True) {
00606        fm = FrameMgrInit(create_ic_fr, (char *)p,
00607                        _Xi18nNeedSwap(i18n_core, connect_id));
00608        /* get data */
00609        FrameMgrGetToken(fm, input_method_ID);
00610        FrameMgrGetToken(fm, byte_length);
00611     } else {
00612        fm = FrameMgrInit(set_ic_values_fr, (char *)p,
00613                        _Xi18nNeedSwap(i18n_core, connect_id));
00614        /* get data */
00615        FrameMgrGetToken(fm, input_method_ID);
00616        FrameMgrGetToken(fm, changeic->icid);
00617        FrameMgrGetToken(fm, byte_length);
00618     }
00619     attrib_list = (XICAttribute *)malloc(sizeof(XICAttribute) * IC_SIZE);
00620     if (!attrib_list) {
00621        _Xi18nSendMessage(ims, connect_id, XIM_ERROR, 0, 0, 0);
00622        return;
00623     }
00624     memset(attrib_list, 0, sizeof(XICAttribute) * IC_SIZE);
00625 
00626     attrib_num = 0;
00627     while (FrameMgrIsIterLoopEnd(fm, &status) == False) {
00628        void *value;
00629        int value_length;
00630        FrameMgrGetToken(fm, attrib_list[attrib_num].attribute_id);
00631        FrameMgrGetToken(fm, value_length);
00632        FrameMgrSetSize(fm, value_length);
00633        attrib_list[attrib_num].value_length = value_length;
00634        FrameMgrGetToken(fm, value);
00635        attrib_list[attrib_num].value = (void *)malloc(value_length + 1);
00636        memmove(attrib_list[attrib_num].value, value, value_length);
00637        attrib_num++;
00638     }
00639 
00640     for (i = 0; i < attrib_num; i++) {
00641        CARD16 number;
00642        if (IsNestedList(i18n_core, attrib_list[i].attribute_id)) {
00643            if (attrib_list[i].attribute_id == i18n_core->address.preeditAttr_id) {
00644               ReadICValue(i18n_core, attrib_list[i].attribute_id,
00645                          attrib_list[i].value_length,
00646                          attrib_list[i].value,
00647                          &pre_attr[preedit_ic_num], &number,
00648                          _Xi18nNeedSwap(i18n_core, connect_id));
00649               preedit_ic_num += number;
00650            } else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id) {
00651               ReadICValue(i18n_core, attrib_list[i].attribute_id,
00652                          attrib_list[i].value_length,
00653                          attrib_list[i].value,
00654                          &sts_attr[status_ic_num], &number,
00655                          _Xi18nNeedSwap(i18n_core, connect_id));
00656               status_ic_num += number;
00657            } else {
00658               /* another nested list.. possible? */
00659            }
00660        } else {
00661            ReadICValue(i18n_core, attrib_list[i].attribute_id,
00662                      attrib_list[i].value_length,
00663                      attrib_list[i].value,
00664                      &ic_attr[ic_num], &number,
00665                      _Xi18nNeedSwap(i18n_core, connect_id));
00666            ic_num +=number;
00667        }
00668     }
00669     for (i = 0; i < attrib_num; i++) {
00670        XFree(attrib_list[i].value);
00671     }
00672     XFree(attrib_list);
00673 
00674     /* free FrameMgr */
00675     FrameMgrFree(fm);
00676 
00677     changeic->preedit_attr_num = preedit_ic_num;
00678     changeic->status_attr_num = status_ic_num;
00679     changeic->ic_attr_num = ic_num;
00680     changeic->preedit_attr = pre_attr;
00681     changeic->status_attr = sts_attr;
00682     changeic->ic_attr = ic_attr;
00683 
00684 #ifdef IM_PROTO_HANDLER
00685     CALL_PROTO_HANDLER;
00686 #else
00687     if (create_flag == True) {
00688       changeic->icid = CreateXIC(ims,
00689                              connect_id,
00690                              preedit_ic_num,
00691                              status_ic_num,
00692                              ic_num,
00693                              pre_attr,
00694                              sts_attr,
00695                              ic_attr);
00696     } else {
00697       SetICValues(changeic->icid,
00698                 preedit_ic_num,
00699                 status_ic_num,
00700                 ic_num,
00701                 pre_attr,
00702                 sts_attr,
00703                 ic_attr);
00704     }
00705 #endif
00706 
00707     /* need to free attr->value of pre_attr, sts_attr, ic_attr */
00708     FreeICAttrValues(preedit_ic_num, status_ic_num, ic_num,
00709                 pre_attr, sts_attr, ic_attr);
00710 
00711     /* create FrameMgr */
00712     if (create_flag == True) {
00713        fm = FrameMgrInit(create_ic_reply_fr, NULL,
00714                        _Xi18nNeedSwap(i18n_core, connect_id));
00715     } else {
00716        fm = FrameMgrInit(set_ic_values_reply_fr, NULL,
00717                        _Xi18nNeedSwap(i18n_core, connect_id));
00718     }
00719     total_size = FrameMgrGetTotalSize(fm);
00720     reply = (unsigned char *)malloc(total_size);
00721     if (!reply) {
00722        _Xi18nSendMessage(ims, connect_id, XIM_ERROR, 0, 0, 0);
00723        return;
00724     }
00725     memset(reply, 0, total_size);
00726     FrameMgrSetBuffer(fm, reply);
00727 
00728     FrameMgrPutToken(fm, input_method_ID);
00729     FrameMgrPutToken(fm, changeic->icid);
00730 
00731     if (create_flag == True) {
00732        _Xi18nSendMessage(ims, connect_id, XIM_CREATE_IC_REPLY, 0,
00733                        reply, total_size);
00734     } else {
00735        _Xi18nSendMessage(ims, connect_id, XIM_SET_IC_VALUES_REPLY, 0,
00736                        reply, total_size);
00737     }
00738     if (create_flag == True) {
00739        int on_key_num = i18n_core->address.on_keys.count_keys;
00740        int off_key_num = i18n_core->address.off_keys.count_keys;
00741 
00742        if (on_key_num == 0 && off_key_num == 0) {
00743            long mask;
00744            if (i18n_core->address.imvalue_mask & I18N_FILTERMASK)
00745              mask = i18n_core->address.filterevent_mask;
00746            else
00747              mask = DEFAULT_FILTER_MASK;
00748            /* static event flow is default */
00749            _Xi18nSetEventMask(ims, connect_id,
00750                             input_method_ID,
00751                             changeic->icid,
00752                             mask, ~mask);
00753        }
00754     }
00755     XFree(reply);
00756     /* free FrameMgr */
00757     FrameMgrFree(fm);
00758     return;
00759 }
00760 
00761 /* called from GetICValueMessageProc */
00762 void
00763 _Xi18nGetIC(XIMS ims, X11R6IMProtocol call_data, unsigned char *p)
00764 {
00765     Xi18n i18n_core = ims->protocol;
00766     FrameMgr fm;
00767     FmStatus status;
00768     extern XimFrameRec get_ic_values_fr[], get_ic_values_reply_fr[];
00769     CARD16 byte_length;
00770     register int total_size;
00771     unsigned char *reply = NULL;
00772     XICAttribute *preedit_ret = NULL, *status_ret = NULL;
00773     register int i, number;
00774     int iter_count;
00775     CARD16 *attrID_list;
00776     XICAttribute pre_attr[IC_SIZE], sts_attr[IC_SIZE], ic_attr[IC_SIZE];
00777     CARD16 pre_count = 0, sts_count = 0, ic_count = 0;
00778     IMChangeICStruct *getic =
00779       (IMChangeICStruct*)&call_data->changeic;
00780     CARD16 connect_id = call_data->any.connect_id;
00781     CARD16 input_method_ID;
00782 
00783     memset(pre_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00784     memset(sts_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00785     memset(ic_attr, 0, sizeof(XICAttribute) * IC_SIZE);
00786 
00787     /* create FrameMgr */
00788     fm = FrameMgrInit(get_ic_values_fr, (char *)p,
00789                     _Xi18nNeedSwap(i18n_core, connect_id));
00790 
00791     /* get data */
00792     FrameMgrGetToken(fm, input_method_ID);
00793     FrameMgrGetToken(fm, getic->icid);
00794     FrameMgrGetToken(fm, byte_length);
00795 
00796     attrID_list = (CARD16 *)malloc(sizeof(CARD16) * IC_SIZE); /* bogus */
00797     memset(attrID_list, 0, sizeof(CARD16) * IC_SIZE);
00798 
00799     number = 0;
00800     while (FrameMgrIsIterLoopEnd(fm, &status) == False) {
00801        FrameMgrGetToken(fm, attrID_list[number]);
00802        number++;
00803     }
00804     /* free FrameMgr */
00805     FrameMgrFree(fm);
00806 
00807     i = 0;
00808     while (i < number) {
00809        int read_number;
00810        if (IsNestedList(i18n_core, attrID_list[i])) {
00811            if (attrID_list[i] == i18n_core->address.preeditAttr_id) {
00812               GetICValue(i18n_core, &pre_attr[pre_count],
00813                         &attrID_list[i], number, &read_number);
00814               i += read_number + 1;
00815               pre_count += read_number;
00816            } else if (attrID_list[i] == i18n_core->address.statusAttr_id) {
00817               GetICValue(i18n_core, &sts_attr[sts_count],
00818                         &attrID_list[i], number, &read_number);
00819               i += read_number + 1;
00820               sts_count += read_number;
00821            } else {
00822               /* another nested list.. possible? */
00823            }
00824        } else {
00825            GetICValue(i18n_core, &ic_attr[ic_count], &attrID_list[i],
00826                      number, &read_number);
00827            i += read_number;
00828            ic_count += read_number;
00829        }
00830     }
00831     getic->preedit_attr_num = pre_count;
00832     getic->status_attr_num = sts_count;
00833     getic->ic_attr_num = ic_count;
00834     getic->preedit_attr = pre_attr;
00835     getic->status_attr = sts_attr;
00836     getic->ic_attr = ic_attr;
00837 
00838     XFree(attrID_list);
00839 
00840 #ifdef IM_PROTO_HANDLER
00841     CALL_PROTO_HANDLER;
00842 #else
00843     GetICValues(getic->icid,
00844               pre_count, sts_count, ic_count,
00845               pre_attr, sts_attr, ic_attr);
00846 #endif
00847 
00848     iter_count = getic->ic_attr_num;
00849 
00850     preedit_ret = CreateNestedList(i18n_core->address.preeditAttr_id,
00851                                getic->preedit_attr,
00852                                getic->preedit_attr_num,
00853                                _Xi18nNeedSwap(i18n_core, connect_id));
00854     if (preedit_ret != NULL)
00855       iter_count++;
00856     status_ret = CreateNestedList(i18n_core->address.statusAttr_id,
00857                               getic->status_attr,
00858                               getic->status_attr_num,
00859                               _Xi18nNeedSwap(i18n_core, connect_id));
00860     if (status_ret != NULL)
00861       iter_count++;
00862 
00863     /* create FrameMgr */
00864     fm = FrameMgrInit(get_ic_values_reply_fr, NULL,
00865                     _Xi18nNeedSwap(i18n_core, connect_id));
00866 
00867     /* set iteration count for list of ic_attribute */
00868     FrameMgrSetIterCount(fm, iter_count);
00869 
00870     /* set length of BARRAY item in xicattribute_fr*/
00871     for (i = 0; i < (int)getic->ic_attr_num; i++) {
00872        FrameMgrSetSize(fm, ic_attr[i].value_length);
00873     }
00874 
00875     if (preedit_ret != NULL)
00876       FrameMgrSetSize(fm, preedit_ret->value_length);
00877     if (status_ret != NULL)
00878       FrameMgrSetSize(fm, status_ret->value_length);
00879 
00880     total_size = FrameMgrGetTotalSize(fm);
00881     reply = (unsigned char *)malloc(total_size);
00882     if (!reply) {
00883        _Xi18nSendMessage(ims, connect_id, XIM_ERROR, 0, 0, 0);
00884        return;
00885     }
00886     memset(reply, 0, total_size);
00887     FrameMgrSetBuffer(fm, reply);
00888 
00889     FrameMgrPutToken(fm, input_method_ID);
00890     FrameMgrPutToken(fm, getic->icid);
00891 
00892     for (i = 0; i < (int)getic->ic_attr_num; i++) {
00893        FrameMgrPutToken(fm, ic_attr[i].attribute_id);
00894        FrameMgrPutToken(fm, ic_attr[i].value_length);
00895        FrameMgrPutToken(fm, ic_attr[i].value);
00896     }
00897     if (preedit_ret != NULL) {
00898        FrameMgrPutToken(fm, preedit_ret->attribute_id);
00899        FrameMgrPutToken(fm, preedit_ret->value_length);
00900        FrameMgrPutToken(fm, preedit_ret->value);
00901     }
00902     if (status_ret != NULL) {
00903        FrameMgrPutToken(fm, status_ret->attribute_id);
00904        FrameMgrPutToken(fm, status_ret->value_length);
00905        FrameMgrPutToken(fm, status_ret->value);
00906     }
00907     _Xi18nSendMessage(ims, connect_id,
00908                     XIM_GET_IC_VALUES_REPLY, 0, reply, total_size);
00909     XFree(reply);
00910 
00911     /* need to free attr->name of pre_attr, sts_attr, ic_attr */
00912     FreeICAttrValues(pre_count, sts_count, ic_count,
00913               pre_attr, sts_attr, ic_attr);
00914 
00915     /* need to free attr->name of pre_attr, sts_attr, ic_attr */
00916     FreeICAttrNames(pre_count, sts_count, ic_count,
00917               pre_attr, sts_attr, ic_attr);
00918 
00919     if (preedit_ret != NULL) {
00920        XFree(preedit_ret->value);
00921        XFree(preedit_ret);
00922     }
00923     if (status_ret != NULL) {
00924        XFree(status_ret->value);
00925        XFree(status_ret);
00926     }
00927     /* free FrameMgr */
00928     FrameMgrFree(fm);
00929     return;
00930 }