Tizen 2.1 base
[platform/core/uifw/ise-engine-sunpinyin.git] / wrapper / xim / IMdkit / i18nPtHdr.c
1 /******************************************************************
2  
3          Copyright 1994, 1995 by Sun Microsystems, Inc.
4          Copyright 1993, 1994 by Hewlett-Packard Company
5  
6 Permission to use, copy, modify, distribute, and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of Sun Microsystems, Inc.
11 and Hewlett-Packard not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior permission.
13 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
14 the suitability of this software for any purpose.  It is provided "as is"
15 without express or implied warranty.
16  
17 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
18 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
23 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25  
26   Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
27
28     This version tidied and debugged by Steve Underwood May 1999
29  
30 ******************************************************************/
31
32 #include <stdlib.h>
33 #include <sys/param.h>
34 #include <X11/Xlib.h>
35 #ifndef NEED_EVENTS
36 #define NEED_EVENTS
37 #endif
38 #include <X11/Xproto.h>
39 #undef NEED_EVENTS
40 #include "FrameMgr.h"
41 #include "IMdkit.h"
42 #include "Xi18n.h"
43 #include "XimFunc.h"
44
45 #ifdef XIM_DEBUG
46 #include <stdio.h>
47
48 static void     DebugLog(char * msg)
49 {
50         fprintf(stderr, msg);
51 }
52 #endif
53
54 extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16);
55
56 static void GetProtocolVersion (CARD16 client_major,
57                                 CARD16 client_minor,
58                                 CARD16 *server_major,
59                                 CARD16 *server_minor)
60 {
61     *server_major = client_major;
62     *server_minor = client_minor;
63 }
64
65 static void ConnectMessageProc (XIMS ims,
66                                 IMProtocol *call_data,
67                                 unsigned char *p)
68 {
69     Xi18n i18n_core = ims->protocol;
70     FrameMgr fm;
71     extern XimFrameRec connect_fr[], connect_reply_fr[];
72     register int total_size;
73     CARD16 server_major_version, server_minor_version;
74     unsigned char *reply = NULL;
75     IMConnectStruct *imconnect =
76         (IMConnectStruct*) &call_data->imconnect;
77     CARD16 connect_id = call_data->any.connect_id;
78
79     fm = FrameMgrInit (connect_fr,
80                        (char *) p,
81                        _Xi18nNeedSwap (i18n_core, connect_id));
82
83     /* get data */
84     FrameMgrGetToken (fm, imconnect->byte_order);
85     FrameMgrGetToken (fm, imconnect->major_version);
86     FrameMgrGetToken (fm, imconnect->minor_version);
87
88     FrameMgrFree (fm);
89
90     GetProtocolVersion (imconnect->major_version,
91                         imconnect->minor_version,
92                         &server_major_version,
93                         &server_minor_version);
94 #ifdef PROTOCOL_RICH
95     if (i18n_core->address.improto)
96     {
97         if (!(i18n_core->address.improto(ims, call_data)))
98             return;
99         /*endif*/
100     }
101     /*endif*/
102 #endif  /* PROTOCOL_RICH */
103
104     fm = FrameMgrInit (connect_reply_fr,
105                        NULL,
106                        _Xi18nNeedSwap (i18n_core, connect_id));
107
108     total_size = FrameMgrGetTotalSize (fm);
109     reply = (unsigned char *) malloc (total_size);
110     if (!reply)
111     {
112         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
113         return;
114     }
115     /*endif*/
116     memset (reply, 0, total_size);
117     FrameMgrSetBuffer (fm, reply);
118
119     FrameMgrPutToken (fm, server_major_version);
120     FrameMgrPutToken (fm, server_minor_version);
121
122     _Xi18nSendMessage (ims,
123                        connect_id,
124                        XIM_CONNECT_REPLY,
125                        0,
126                        reply,
127                        total_size);
128
129     FrameMgrFree (fm);
130     XFree (reply);
131 }
132
133 static void DisConnectMessageProc (XIMS ims, IMProtocol *call_data)
134 {
135     Xi18n i18n_core = ims->protocol;
136     unsigned char *reply = NULL;
137     CARD16 connect_id = call_data->any.connect_id;
138
139 #ifdef PROTOCOL_RICH
140     if (i18n_core->address.improto)
141     {
142         if (!(i18n_core->address.improto (ims, call_data)))
143             return;
144         /*endif*/
145     }
146     /*endif*/
147 #endif  /* PROTOCOL_RICH */
148
149     _Xi18nSendMessage (ims,
150                        connect_id,
151                        XIM_DISCONNECT_REPLY,
152                        0,
153                        reply,
154                        0);
155
156     i18n_core->methods.disconnect (ims, connect_id);
157 }
158
159 static void OpenMessageProc(XIMS ims, IMProtocol *call_data, unsigned char *p)
160 {
161     Xi18n i18n_core = ims->protocol;
162     FrameMgr fm;
163     extern XimFrameRec open_fr[];
164     extern XimFrameRec open_reply_fr[];
165     unsigned char *reply = NULL;
166     int str_size;
167     register int i, total_size;
168     CARD16 connect_id = call_data->any.connect_id;
169     int str_length;
170     char *name;
171     IMOpenStruct *imopen = (IMOpenStruct *) &call_data->imopen;
172
173     fm = FrameMgrInit (open_fr,
174                        (char *) p,
175                        _Xi18nNeedSwap (i18n_core, connect_id));
176
177     /* get data */
178     FrameMgrGetToken (fm, str_length);
179     FrameMgrSetSize (fm, str_length);
180     FrameMgrGetToken (fm, name);
181     imopen->lang.length = str_length;
182     imopen->lang.name = malloc (str_length + 1);
183     strncpy (imopen->lang.name, name, str_length);
184     imopen->lang.name[str_length] = (char) 0;
185
186     FrameMgrFree (fm);
187
188     if (i18n_core->address.improto)
189     {
190         if (!(i18n_core->address.improto(ims, call_data)))
191             return;
192         /*endif*/
193     }
194     /*endif*/
195     if ((i18n_core->address.imvalue_mask & I18N_ON_KEYS)
196         ||
197         (i18n_core->address.imvalue_mask & I18N_OFF_KEYS))
198     {
199         _Xi18nSendTriggerKey (ims, connect_id);
200     }
201     /*endif*/
202     XFree (imopen->lang.name);
203
204     fm = FrameMgrInit (open_reply_fr,
205                        NULL,
206                        _Xi18nNeedSwap (i18n_core, connect_id));
207
208     /* set iteration count for list of imattr */
209     FrameMgrSetIterCount (fm, i18n_core->address.im_attr_num);
210
211     /* set length of BARRAY item in ximattr_fr */
212     for (i = 0;  i < i18n_core->address.im_attr_num;  i++)
213     {
214         str_size = strlen (i18n_core->address.xim_attr[i].name);
215         FrameMgrSetSize (fm, str_size);
216     }
217     /*endfor*/
218     /* set iteration count for list of icattr */
219     FrameMgrSetIterCount (fm, i18n_core->address.ic_attr_num);
220     /* set length of BARRAY item in xicattr_fr */
221     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++)
222     {
223         str_size = strlen (i18n_core->address.xic_attr[i].name);
224         FrameMgrSetSize (fm, str_size);
225     }
226     /*endfor*/
227
228     total_size = FrameMgrGetTotalSize (fm);
229     reply = (unsigned char *) malloc (total_size);
230     if (!reply)
231     {
232         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
233         return;
234     }
235     /*endif*/
236     memset (reply, 0, total_size);
237     FrameMgrSetBuffer (fm, reply);
238
239     /* input input-method ID */
240     FrameMgrPutToken (fm, connect_id);
241
242     for (i = 0;  i < i18n_core->address.im_attr_num;  i++)
243     {
244         str_size = FrameMgrGetSize (fm);
245         FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].attribute_id);
246         FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].type);
247         FrameMgrPutToken (fm, str_size);
248         FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].name);
249     }
250     /*endfor*/
251     for (i = 0;  i < i18n_core->address.ic_attr_num;  i++)
252     {
253         str_size = FrameMgrGetSize (fm);
254         FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].attribute_id);
255         FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].type);
256         FrameMgrPutToken (fm, str_size);
257         FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].name);
258     }
259     /*endfor*/
260
261     _Xi18nSendMessage (ims,
262                        connect_id,
263                        XIM_OPEN_REPLY,
264                        0,
265                        reply,
266                        total_size);
267
268     FrameMgrFree (fm);
269     XFree (reply);
270 }
271
272 static void CloseMessageProc (XIMS ims,
273                               IMProtocol *call_data,
274                               unsigned char *p)
275 {
276     Xi18n i18n_core = ims->protocol;
277     FrameMgr fm;
278     extern XimFrameRec close_fr[];
279     extern XimFrameRec close_reply_fr[];
280     unsigned char *reply = NULL;
281     register int total_size;
282     CARD16 connect_id = call_data->any.connect_id;
283     CARD16 input_method_ID;
284
285     fm = FrameMgrInit (close_fr,
286                        (char *) p,
287                        _Xi18nNeedSwap (i18n_core, connect_id));
288
289     FrameMgrGetToken (fm, input_method_ID);
290
291     FrameMgrFree (fm);
292
293     if (i18n_core->address.improto)
294     {
295         if (!(i18n_core->address.improto (ims, call_data)))
296             return;
297         /*endif*/
298     }
299     /*endif*/
300
301     fm = FrameMgrInit (close_reply_fr,
302                        NULL,
303                        _Xi18nNeedSwap (i18n_core, connect_id));
304
305     total_size = FrameMgrGetTotalSize (fm);
306     reply = (unsigned char *) malloc (total_size);
307     if (!reply)
308     {
309         _Xi18nSendMessage (ims,
310                            connect_id,
311                            XIM_ERROR,
312                            0,
313                            0,
314                            0);
315         return;
316     }
317     /*endif*/
318     memset (reply, 0, total_size);
319     FrameMgrSetBuffer (fm, reply);
320
321     FrameMgrPutToken (fm, input_method_ID);
322
323     _Xi18nSendMessage (ims,
324                        connect_id,
325                        XIM_CLOSE_REPLY,
326                        0,
327                        reply,
328                        total_size);
329
330     FrameMgrFree (fm);
331     XFree (reply);
332 }
333
334 static XIMExt *MakeExtensionList (Xi18n i18n_core,
335                                   XIMStr *lib_extension,
336                                   int number,
337                                   int *reply_number)
338 {
339     XIMExt *ext_list;
340     XIMExt *im_ext = (XIMExt *) i18n_core->address.extension;
341     int im_ext_len = i18n_core->address.ext_num;
342     int i;
343     int j;
344
345     *reply_number = 0;
346
347     if (number == 0)
348     {
349         /* query all extensions */
350         *reply_number = im_ext_len;
351     }
352     else
353     {
354         for (i = 0;  i < im_ext_len;  i++)
355         {
356             for (j = 0;  j < (int) number;  j++)
357             {
358                 if (strcmp (lib_extension[j].name, im_ext[i].name) == 0)
359                 {
360                     (*reply_number)++;
361                     break;
362                 }
363                 /*endif*/
364             }
365             /*endfor*/
366         }
367         /*endfor*/
368     }
369     /*endif*/
370
371     if (!(*reply_number))
372         return NULL;
373     /*endif*/
374     ext_list = (XIMExt *) malloc (sizeof (XIMExt)*(*reply_number));
375     if (!ext_list)
376         return NULL;
377     /*endif*/
378     memset (ext_list, 0, sizeof (XIMExt)*(*reply_number));
379
380     if (number == 0)
381     {
382         /* query all extensions */
383         for (i = 0;  i < im_ext_len;  i++)
384         {
385             ext_list[i].major_opcode = im_ext[i].major_opcode;
386             ext_list[i].minor_opcode = im_ext[i].minor_opcode;
387             ext_list[i].length = im_ext[i].length;
388             ext_list[i].name = malloc (im_ext[i].length + 1);
389             strcpy (ext_list[i].name, im_ext[i].name);
390         }
391         /*endfor*/
392     }
393     else
394     {
395         int n = 0;
396
397         for (i = 0;  i < im_ext_len;  i++)
398         {
399             for (j = 0;  j < (int)number;  j++)
400             {
401                 if (strcmp (lib_extension[j].name, im_ext[i].name) == 0)
402                 {
403                     ext_list[n].major_opcode = im_ext[i].major_opcode;
404                     ext_list[n].minor_opcode = im_ext[i].minor_opcode;
405                     ext_list[n].length = im_ext[i].length;
406                     ext_list[n].name = malloc (im_ext[i].length + 1);
407                     strcpy (ext_list[n].name, im_ext[i].name);
408                     n++;
409                     break;
410                 }
411                 /*endif*/
412             }
413             /*endfor*/
414         }
415         /*endfor*/
416     }
417     /*endif*/
418     return ext_list;
419 }
420
421 static void QueryExtensionMessageProc (XIMS ims,
422                                        IMProtocol *call_data,
423                                        unsigned char *p)
424 {
425     Xi18n i18n_core = ims->protocol;
426     FrameMgr fm;
427     FmStatus status;
428     extern XimFrameRec query_extension_fr[];
429     extern XimFrameRec query_extension_reply_fr[];
430     unsigned char *reply = NULL;
431     int str_size;
432     register int i;
433     register int number;
434     register int total_size;
435     int byte_length;
436     int reply_number = 0;
437     XIMExt *ext_list;
438     IMQueryExtensionStruct *query_ext =
439         (IMQueryExtensionStruct *) &call_data->queryext;
440     CARD16 connect_id = call_data->any.connect_id;
441     CARD16 input_method_ID;
442
443     fm = FrameMgrInit (query_extension_fr,
444                        (char *) p,
445                        _Xi18nNeedSwap (i18n_core, connect_id));
446
447     FrameMgrGetToken (fm, input_method_ID);
448     FrameMgrGetToken (fm, byte_length);
449     query_ext->extension = (XIMStr *) malloc (sizeof (XIMStr)*10);
450     memset (query_ext->extension, 0, sizeof (XIMStr)*10);
451     number = 0;
452     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
453     {
454         char *name;
455         int str_length;
456         
457         FrameMgrGetToken (fm, str_length);
458         FrameMgrSetSize (fm, str_length);
459         query_ext->extension[number].length = str_length;
460         FrameMgrGetToken (fm, name);
461         query_ext->extension[number].name = malloc (str_length + 1);
462         strncpy (query_ext->extension[number].name, name, str_length);
463         query_ext->extension[number].name[str_length] = (char) 0;
464         number++;
465     }
466     /*endwhile*/
467     query_ext->number = number;
468
469 #ifdef PROTOCOL_RICH
470     if (i18n_core->address.improto)
471     {
472         if (!(i18n_core->address.improto(ims, call_data)))
473             return;
474         /*endif*/
475     }
476     /*endif*/
477 #endif  /* PROTOCOL_RICH */
478
479     FrameMgrFree (fm);
480
481     ext_list = MakeExtensionList (i18n_core,
482                                   query_ext->extension,
483                                   number,
484                                   &reply_number);
485
486     for (i = 0;  i < number;  i++)
487         XFree (query_ext->extension[i].name);
488     /*endfor*/
489     XFree (query_ext->extension);
490
491     fm = FrameMgrInit (query_extension_reply_fr,
492                        NULL,
493                        _Xi18nNeedSwap (i18n_core, connect_id));
494
495     /* set iteration count for list of extensions */
496     FrameMgrSetIterCount (fm, reply_number);
497
498     /* set length of BARRAY item in ext_fr */
499     for (i = 0;  i < reply_number;  i++)
500     {
501         str_size = strlen (ext_list[i].name);
502         FrameMgrSetSize (fm, str_size);
503     }
504     /*endfor*/
505
506     total_size = FrameMgrGetTotalSize (fm);
507     reply = (unsigned char *) malloc (total_size);
508     if (!reply)
509     {
510         _Xi18nSendMessage (ims,
511                            connect_id,
512                            XIM_ERROR,
513                            0,
514                            0,
515                            0);
516         return;
517     }
518     /*endif*/
519     memset (reply, 0, total_size);
520     FrameMgrSetBuffer (fm, reply);
521
522     FrameMgrPutToken (fm, input_method_ID);
523
524     for (i = 0;  i < reply_number;  i++)
525     {
526         str_size = FrameMgrGetSize (fm);
527         FrameMgrPutToken (fm, ext_list[i].major_opcode);
528         FrameMgrPutToken (fm, ext_list[i].minor_opcode);
529         FrameMgrPutToken (fm, str_size);
530         FrameMgrPutToken (fm, ext_list[i].name);
531     }
532     /*endfor*/
533     _Xi18nSendMessage (ims,
534                        connect_id,
535                        XIM_QUERY_EXTENSION_REPLY,
536                        0,
537                        reply,
538                        total_size);
539     FrameMgrFree (fm);
540     XFree (reply);
541
542     for (i = 0;  i < reply_number;  i++)
543         XFree (ext_list[i].name);
544     /*endfor*/
545     XFree ((char *) ext_list);
546 }
547
548 static void SyncReplyMessageProc (XIMS ims,
549                                   IMProtocol *call_data,
550                                   unsigned char *p)
551 {
552     Xi18n i18n_core = ims->protocol;
553     FrameMgr fm;
554     extern XimFrameRec sync_reply_fr[];
555     CARD16 connect_id = call_data->any.connect_id;
556     Xi18nClient *client;
557     CARD16 input_method_ID;
558     CARD16 input_context_ID;
559
560     client = (Xi18nClient *)_Xi18nFindClient (i18n_core, connect_id);
561     fm = FrameMgrInit (sync_reply_fr,
562                        (char *) p,
563                        _Xi18nNeedSwap (i18n_core, connect_id));
564     FrameMgrGetToken (fm, input_method_ID);
565     FrameMgrGetToken (fm, input_context_ID);
566     FrameMgrFree (fm);
567
568     client->sync = False;
569
570     if (ims->sync == True) {
571         ims->sync = False;
572         if (i18n_core->address.improto) {
573             call_data->sync_xlib.major_code = XIM_SYNC_REPLY;
574             call_data->sync_xlib.minor_code = 0;
575             call_data->sync_xlib.connect_id = input_method_ID;
576             call_data->sync_xlib.icid = input_context_ID;
577             i18n_core->address.improto(ims, call_data);
578         }
579     }
580 }
581
582 static void GetIMValueFromName (Xi18n i18n_core,
583                                 CARD16 connect_id,
584                                 char *buf,
585                                 char *name,
586                                 int *length)
587 {
588     register int i;
589
590     if (strcmp (name, XNQueryInputStyle) == 0)
591     {
592         XIMStyles *styles = (XIMStyles *) &i18n_core->address.input_styles;
593
594         *length = sizeof (CARD16)*2;    /* count_styles, unused */
595         *length += styles->count_styles*sizeof (CARD32);
596
597         if (buf != NULL)
598         {
599             FrameMgr fm;
600             extern XimFrameRec input_styles_fr[];
601             unsigned char *data = NULL;
602             int total_size;
603             
604             fm = FrameMgrInit (input_styles_fr,
605                                NULL,
606                                _Xi18nNeedSwap (i18n_core, connect_id));
607
608             /* set iteration count for list of input_style */
609             FrameMgrSetIterCount (fm, styles->count_styles);
610
611             total_size = FrameMgrGetTotalSize (fm);
612             data = (unsigned char *) malloc (total_size);
613             if (!data)
614                 return;
615             /*endif*/
616             memset (data, 0, total_size);
617             FrameMgrSetBuffer (fm, data);
618
619             FrameMgrPutToken (fm, styles->count_styles);
620             for (i = 0;  i < (int) styles->count_styles;  i++)
621                 FrameMgrPutToken (fm, styles->supported_styles[i]);
622             /*endfor*/
623             memmove (buf, data, total_size);
624             FrameMgrFree (fm);
625
626             /* ADDED BY SUZHE */
627             free (data);
628             /* ADDED BY SUZHE */
629         }
630         /*endif*/
631     }
632     /*endif*/
633
634     else if (strcmp (name, XNQueryIMValuesList) == 0) {
635     }
636 }
637
638 static XIMAttribute *MakeIMAttributeList (Xi18n i18n_core,
639                                           CARD16 connect_id,
640                                           CARD16 *list,
641                                           int *number,
642                                           int *length)
643 {
644     XIMAttribute *attrib_list;
645     int list_num;
646     XIMAttr *attr = i18n_core->address.xim_attr;
647     int list_len = i18n_core->address.im_attr_num;
648     register int i;
649     register int j;
650     int value_length;
651     int number_ret = 0;
652
653     *length = 0;
654     list_num = 0;
655     for (i = 0;  i < *number;  i++)
656     {
657         for (j = 0;  j < list_len;  j++)
658         {
659             if (attr[j].attribute_id == list[i])
660             {
661                 list_num++;
662                 break;
663             }
664             /*endif*/
665         }
666         /*endfor*/
667     }
668     /*endfor*/
669     attrib_list = (XIMAttribute *) malloc (sizeof (XIMAttribute)*list_num);
670     if (!attrib_list)
671         return NULL;
672     /*endif*/
673     memset (attrib_list, 0, sizeof (XIMAttribute)*list_num);
674     number_ret = list_num;
675     list_num = 0;
676     for (i = 0;  i < *number;  i++)
677     {
678         for (j = 0;  j < list_len;  j++)
679         {
680             if (attr[j].attribute_id == list[i])
681             {
682                 attrib_list[list_num].attribute_id = attr[j].attribute_id;
683                 attrib_list[list_num].name_length = attr[j].length;
684                 attrib_list[list_num].name = attr[j].name;
685                 attrib_list[list_num].type = attr[j].type;
686                 GetIMValueFromName (i18n_core,
687                                     connect_id,
688                                     NULL,
689                                     attr[j].name,
690                                     &value_length);
691                 attrib_list[list_num].value_length = value_length;
692                 attrib_list[list_num].value = (void *) malloc (value_length);
693                 memset(attrib_list[list_num].value, 0, value_length);
694                 GetIMValueFromName (i18n_core,
695                                     connect_id,
696                                     attrib_list[list_num].value,
697                                     attr[j].name,
698                                     &value_length);
699                 *length += sizeof (CARD16)*2;
700                 *length += value_length;
701                 *length += IMPAD (value_length);
702                 list_num++;
703                 break;
704             }
705             /*endif*/
706         }
707         /*endfor*/
708     }
709     /*endfor*/
710     *number = number_ret;
711     return attrib_list;
712 }
713
714 static void GetIMValuesMessageProc (XIMS ims,
715                                     IMProtocol *call_data,
716                                     unsigned char *p)
717 {
718     Xi18n i18n_core = ims->protocol;
719     FrameMgr fm;
720     FmStatus status;
721     extern XimFrameRec get_im_values_fr[];
722     extern XimFrameRec get_im_values_reply_fr[];
723     CARD16 byte_length;
724     int list_len, total_size;
725     unsigned char *reply = NULL;
726     int iter_count;
727     register int i;
728     register int j;
729     int number;
730     CARD16 *im_attrID_list;
731     char **name_list;
732     CARD16 name_number;
733     XIMAttribute *im_attribute_list;
734     IMGetIMValuesStruct *getim = (IMGetIMValuesStruct *)&call_data->getim;
735     CARD16 connect_id = call_data->any.connect_id;
736     CARD16 input_method_ID;
737
738     /* create FrameMgr */
739     fm = FrameMgrInit (get_im_values_fr,
740                        (char *) p,
741                        _Xi18nNeedSwap (i18n_core, connect_id));
742
743     FrameMgrGetToken (fm, input_method_ID);
744     FrameMgrGetToken (fm, byte_length);
745     im_attrID_list = (CARD16 *) malloc (sizeof (CARD16)*20);
746     memset (im_attrID_list, 0, sizeof (CARD16)*20);
747     name_list = (char **)malloc(sizeof(char *) * 20);
748     memset(name_list, 0, sizeof(char *) * 20);
749     number = 0;
750     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
751     {
752         FrameMgrGetToken (fm, im_attrID_list[number]);
753         number++;
754     }
755     FrameMgrFree (fm);
756
757     name_number = 0;
758     for (i = 0;  i < number;  i++) {
759         for (j = 0;  j < i18n_core->address.im_attr_num;  j++) {
760             if (i18n_core->address.xim_attr[j].attribute_id ==
761                     im_attrID_list[i]) {
762                 name_list[name_number++] = 
763                         i18n_core->address.xim_attr[j].name;
764                 break;
765             }
766         }
767     }
768     getim->number = name_number;
769     getim->im_attr_list = name_list;
770     XFree (name_list);
771
772
773 #ifdef PROTOCOL_RICH
774     if (i18n_core->address.improto) {
775         if (!(i18n_core->address.improto (ims, call_data)))
776             return;
777     }
778 #endif  /* PROTOCOL_RICH */
779
780     im_attribute_list = MakeIMAttributeList (i18n_core,
781                                              connect_id,
782                                              im_attrID_list,
783                                              &number,
784                                              &list_len);
785     if (im_attrID_list)
786         XFree (im_attrID_list);
787     /*endif*/
788
789     fm = FrameMgrInit (get_im_values_reply_fr,
790                        NULL,
791                        _Xi18nNeedSwap (i18n_core, connect_id));
792
793     iter_count = number;
794
795     /* set iteration count for list of im_attribute */
796     FrameMgrSetIterCount (fm, iter_count);
797
798     /* set length of BARRAY item in ximattribute_fr */
799     for (i = 0;  i < iter_count;  i++)
800         FrameMgrSetSize (fm, im_attribute_list[i].value_length);
801     /*endfor*/
802     
803     total_size = FrameMgrGetTotalSize (fm);
804     reply = (unsigned char *) malloc (total_size);
805     if (!reply)
806     {
807         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
808         return;
809     }
810     /*endif*/
811     memset (reply, 0, total_size);
812     FrameMgrSetBuffer (fm, reply);
813
814     FrameMgrPutToken (fm, input_method_ID);
815
816     for (i = 0;  i < iter_count;  i++)
817     {
818         FrameMgrPutToken (fm, im_attribute_list[i].attribute_id);
819         FrameMgrPutToken (fm, im_attribute_list[i].value_length);
820         FrameMgrPutToken (fm, im_attribute_list[i].value);
821     }
822     /*endfor*/
823     _Xi18nSendMessage (ims,
824                        connect_id,
825                        XIM_GET_IM_VALUES_REPLY,
826                        0,
827                        reply,
828                        total_size);
829     FrameMgrFree (fm);
830     XFree (reply);
831
832     for (i = 0; i < iter_count; i++)
833         XFree(im_attribute_list[i].value);
834     XFree (im_attribute_list);
835 }
836
837 static void CreateICMessageProc (XIMS ims,
838                                  IMProtocol *call_data,
839                                  unsigned char *p)
840 {
841     _Xi18nChangeIC (ims, call_data, p, True);
842 }
843
844 static void SetICValuesMessageProc (XIMS ims,
845                                     IMProtocol *call_data,
846                                     unsigned char *p)
847 {
848     _Xi18nChangeIC (ims, call_data, p, False);
849 }
850
851 static void GetICValuesMessageProc (XIMS ims,
852                                     IMProtocol *call_data,
853                                     unsigned char *p)
854 {
855     _Xi18nGetIC (ims, call_data, p);
856 }
857
858 static void SetICFocusMessageProc (XIMS ims,
859                                    IMProtocol *call_data,
860                                    unsigned char *p)
861 {
862     Xi18n i18n_core = ims->protocol;
863     FrameMgr fm;
864     extern XimFrameRec set_ic_focus_fr[];
865     IMChangeFocusStruct *setfocus;
866     CARD16 connect_id = call_data->any.connect_id;
867     CARD16 input_method_ID;
868
869     setfocus = (IMChangeFocusStruct *) &call_data->changefocus;
870
871     fm = FrameMgrInit (set_ic_focus_fr,
872                        (char *) p,
873                        _Xi18nNeedSwap (i18n_core, connect_id));
874
875     /* get data */
876     FrameMgrGetToken (fm, input_method_ID);
877     FrameMgrGetToken (fm, setfocus->icid);
878
879     FrameMgrFree (fm);
880
881     if (i18n_core->address.improto)
882     {
883         if (!(i18n_core->address.improto (ims, call_data)))
884             return;
885         /*endif*/
886     }
887     /*endif*/
888 }
889
890 static void UnsetICFocusMessageProc (XIMS ims,
891                                      IMProtocol *call_data,
892                                      unsigned char *p)
893 {
894     Xi18n i18n_core = ims->protocol;
895     FrameMgr fm;
896     extern XimFrameRec unset_ic_focus_fr[];
897     IMChangeFocusStruct *unsetfocus;
898     CARD16 connect_id = call_data->any.connect_id;
899     CARD16 input_method_ID;
900
901     unsetfocus = (IMChangeFocusStruct *) &call_data->changefocus;
902
903     fm = FrameMgrInit (unset_ic_focus_fr,
904                        (char *) p,
905                        _Xi18nNeedSwap (i18n_core, connect_id));
906
907     /* get data */
908     FrameMgrGetToken (fm, input_method_ID);
909     FrameMgrGetToken (fm, unsetfocus->icid);
910
911     FrameMgrFree (fm);
912
913     if (i18n_core->address.improto)
914     {
915         if (!(i18n_core->address.improto (ims, call_data)))
916             return;
917         /*endif*/
918     }
919     /*endif*/
920 }
921
922 static void DestroyICMessageProc (XIMS ims,
923                                   IMProtocol *call_data,
924                                   unsigned char *p)
925 {
926     Xi18n i18n_core = ims->protocol;
927     FrameMgr fm;
928     extern XimFrameRec destroy_ic_fr[];
929     extern XimFrameRec destroy_ic_reply_fr[];
930     register int total_size;
931     unsigned char *reply = NULL;
932     IMDestroyICStruct *destroy =
933         (IMDestroyICStruct *) &call_data->destroyic;
934     CARD16 connect_id = call_data->any.connect_id;
935     CARD16 input_method_ID;
936
937     fm = FrameMgrInit (destroy_ic_fr,
938                        (char *) p,
939                        _Xi18nNeedSwap (i18n_core, connect_id));
940
941     /* get data */
942     FrameMgrGetToken (fm, input_method_ID);
943     FrameMgrGetToken (fm, destroy->icid);
944
945     FrameMgrFree (fm);
946
947     if (i18n_core->address.improto)
948     {
949         if (!(i18n_core->address.improto (ims, call_data)))
950             return;
951         /*endif*/
952     }
953     /*endif*/
954     
955     fm = FrameMgrInit (destroy_ic_reply_fr,
956                        NULL,
957                        _Xi18nNeedSwap (i18n_core, connect_id));
958
959     total_size = FrameMgrGetTotalSize (fm);
960     reply = (unsigned char *) malloc (total_size);
961     if (!reply)
962     {
963         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
964         return;
965     }
966     /*endif*/
967     memset (reply, 0, total_size);
968     FrameMgrSetBuffer (fm, reply);
969
970     FrameMgrPutToken (fm, input_method_ID);
971     FrameMgrPutToken (fm, destroy->icid);
972
973     _Xi18nSendMessage (ims,
974                        connect_id,
975                        XIM_DESTROY_IC_REPLY,
976                        0,
977                        reply,
978                        total_size);
979     XFree(reply);
980     FrameMgrFree (fm);
981 }
982
983 static void ResetICMessageProc (XIMS ims,
984                                 IMProtocol *call_data,
985                                 unsigned char *p)
986 {
987     Xi18n i18n_core = ims->protocol;
988     FrameMgr fm;
989     extern XimFrameRec reset_ic_fr[];
990     extern XimFrameRec reset_ic_reply_fr[];
991     register int total_size;
992     unsigned char *reply = NULL;
993     IMResetICStruct *resetic =
994         (IMResetICStruct *) &call_data->resetic;
995     CARD16 connect_id = call_data->any.connect_id;
996     CARD16 input_method_ID;
997
998     fm = FrameMgrInit (reset_ic_fr,
999                        (char *) p,
1000                        _Xi18nNeedSwap (i18n_core, connect_id));
1001
1002     /* get data */
1003     FrameMgrGetToken (fm, input_method_ID);
1004     FrameMgrGetToken (fm, resetic->icid);
1005
1006     FrameMgrFree (fm);
1007
1008     if (i18n_core->address.improto)
1009     {
1010         if (!(i18n_core->address.improto(ims, call_data)))
1011             return;
1012         /*endif*/
1013     }
1014     /*endif*/
1015     
1016     /* create FrameMgr */
1017     fm = FrameMgrInit (reset_ic_reply_fr,
1018                        NULL,
1019                        _Xi18nNeedSwap (i18n_core, connect_id));
1020
1021     /* set length of STRING8 */
1022     FrameMgrSetSize (fm, resetic->length);
1023
1024     total_size = FrameMgrGetTotalSize (fm);
1025     reply = (unsigned char *) malloc (total_size);
1026     if (!reply)
1027     {
1028         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1029         return;
1030     }
1031     /*endif*/
1032     memset (reply, 0, total_size);
1033     FrameMgrSetBuffer (fm, reply);
1034
1035     FrameMgrPutToken (fm, input_method_ID);
1036     FrameMgrPutToken (fm, resetic->icid);
1037     FrameMgrPutToken(fm, resetic->length);
1038     FrameMgrPutToken (fm, resetic->commit_string);
1039
1040     _Xi18nSendMessage (ims,
1041                        connect_id,
1042                        XIM_RESET_IC_REPLY,
1043                        0,
1044                        reply,
1045                        total_size);
1046     FrameMgrFree (fm);
1047     XFree(reply);
1048 }
1049
1050 static int WireEventToEvent (Xi18n i18n_core,
1051                              xEvent *event,
1052                              CARD16 serial,
1053                              XEvent *ev,
1054                              Bool byte_swap)
1055 {
1056     FrameMgr fm;
1057     extern XimFrameRec wire_keyevent_fr[];
1058     BYTE b;
1059     CARD16 c16;
1060     CARD32 c32;
1061     int ret = False;
1062
1063     /* create FrameMgr */
1064     fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap);
1065
1066
1067     /* get & set type */
1068     FrameMgrGetToken(fm, b);
1069     ev->type = (unsigned int)b;
1070     /* get detail */
1071     FrameMgrGetToken(fm, b);
1072     /* get & set serial */
1073     FrameMgrGetToken(fm, c16);
1074     ev->xany.serial = (unsigned long)c16;
1075     ev->xany.serial |= serial << 16;
1076     ev->xany.send_event = False;
1077     ev->xany.display = i18n_core->address.dpy;
1078
1079     /* Remove SendEvent flag from event type to emulate KeyPress/Release */
1080     ev->type &= 0x7F;
1081
1082     switch (ev->type) {
1083       case KeyPress:
1084       case KeyRelease:
1085       {
1086           XKeyEvent *kev = (XKeyEvent*)ev;
1087
1088           /* set keycode (detail) */
1089           kev->keycode = (unsigned int)b;
1090
1091           /* get & set values */
1092           FrameMgrGetToken(fm, c32); kev->time = (Time)c32;
1093           FrameMgrGetToken(fm, c32); kev->root = (Window)c32;
1094           FrameMgrGetToken(fm, c32); kev->window = (Window)c32;
1095           FrameMgrGetToken(fm, c32); kev->subwindow = (Window)c32;
1096           FrameMgrGetToken(fm, c16); kev->x_root = (int)c16;
1097           FrameMgrGetToken(fm, c16); kev->y_root = (int)c16;
1098           FrameMgrGetToken(fm, c16); kev->x = (int)c16;
1099           FrameMgrGetToken(fm, c16); kev->y = (int)c16;
1100           FrameMgrGetToken(fm, c16); kev->state = (unsigned int)c16;
1101           FrameMgrGetToken(fm, b);   kev->same_screen = (Bool)b;
1102       }
1103       ret = True;
1104       break;
1105       default:
1106       break;
1107     }
1108     /* free FrameMgr */
1109     FrameMgrFree(fm);
1110     return ret;
1111 }
1112
1113 static void ForwardEventMessageProc (XIMS ims,
1114                                      IMProtocol *call_data,
1115                                      unsigned char *p)
1116 {
1117     Xi18n i18n_core = ims->protocol;
1118     FrameMgr fm;
1119     extern XimFrameRec forward_event_fr[];
1120     xEvent wire_event;
1121     IMForwardEventStruct *forward =
1122         (IMForwardEventStruct*) &call_data->forwardevent;
1123     CARD16 connect_id = call_data->any.connect_id;
1124     CARD16 input_method_ID;
1125
1126     fm = FrameMgrInit (forward_event_fr,
1127                        (char *) p,
1128                        _Xi18nNeedSwap (i18n_core, connect_id));
1129     /* get data */
1130     FrameMgrGetToken (fm, input_method_ID);
1131     FrameMgrGetToken (fm, forward->icid);
1132     FrameMgrGetToken (fm, forward->sync_bit);
1133     FrameMgrGetToken (fm, forward->serial_number);
1134     p += sizeof (CARD16)*4;
1135     memmove (&wire_event, p, sizeof (xEvent));
1136
1137     FrameMgrFree (fm);
1138
1139     if (WireEventToEvent (i18n_core,
1140                           &wire_event,
1141                           forward->serial_number,
1142                           &forward->event,
1143                           _Xi18nNeedSwap (i18n_core, connect_id)) == True)
1144     {
1145         if (i18n_core->address.improto)
1146         {
1147             if (!(i18n_core->address.improto(ims, call_data)))
1148                 return;
1149             /*endif*/
1150         }
1151         /*endif*/
1152     }
1153     /*endif*/
1154 }
1155
1156 static void ExtForwardKeyEventMessageProc (XIMS ims,
1157                                            IMProtocol *call_data,
1158                                            unsigned char *p)
1159 {
1160     Xi18n i18n_core = ims->protocol;
1161     FrameMgr fm;
1162     extern XimFrameRec ext_forward_keyevent_fr[];
1163     CARD8 type, keycode;
1164     CARD16 state;
1165     CARD32 ev_time, window;
1166     IMForwardEventStruct *forward =
1167         (IMForwardEventStruct *) &call_data->forwardevent;
1168     XEvent *ev = (XEvent *) &forward->event;
1169     CARD16 connect_id = call_data->any.connect_id;
1170     CARD16 input_method_ID;
1171
1172     fm = FrameMgrInit (ext_forward_keyevent_fr,
1173                        (char *) p,
1174                        _Xi18nNeedSwap (i18n_core, connect_id));
1175     /* get data */
1176     FrameMgrGetToken (fm, input_method_ID);
1177     FrameMgrGetToken (fm, forward->icid);
1178     FrameMgrGetToken (fm, forward->sync_bit);
1179     FrameMgrGetToken (fm, forward->serial_number);
1180     FrameMgrGetToken (fm, type);
1181     FrameMgrGetToken (fm, keycode);
1182     FrameMgrGetToken (fm, state);
1183     FrameMgrGetToken (fm, ev_time);
1184     FrameMgrGetToken (fm, window);
1185
1186     FrameMgrFree (fm);
1187
1188     if (type != KeyPress)
1189     {
1190         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1191         return;
1192     }
1193     /*endif*/
1194     
1195     /* make a faked keypress event */
1196     ev->type = (int)type;
1197     ev->xany.send_event = True;
1198     ev->xany.display = i18n_core->address.dpy;
1199     ev->xany.serial = (unsigned long) forward->serial_number;
1200     ((XKeyEvent *) ev)->keycode = (unsigned int) keycode;
1201     ((XKeyEvent *) ev)->state = (unsigned int) state;
1202     ((XKeyEvent *) ev)->time = (Time) ev_time;
1203     ((XKeyEvent *) ev)->window = (Window) window;
1204     ((XKeyEvent *) ev)->root = DefaultRootWindow (ev->xany.display);
1205     ((XKeyEvent *) ev)->x = 0;
1206     ((XKeyEvent *) ev)->y = 0;
1207     ((XKeyEvent *) ev)->x_root = 0;
1208     ((XKeyEvent *) ev)->y_root = 0;
1209
1210     if (i18n_core->address.improto)
1211     {
1212         if (!(i18n_core->address.improto (ims, call_data)))
1213             return;
1214         /*endif*/
1215     }
1216     /*endif*/
1217 }
1218
1219 static void ExtMoveMessageProc (XIMS ims,
1220                                 IMProtocol *call_data,
1221                                 unsigned char *p)
1222 {
1223     Xi18n i18n_core = ims->protocol;
1224     FrameMgr fm;
1225     extern XimFrameRec ext_move_fr[];
1226     IMMoveStruct *extmove =
1227         (IMMoveStruct*) & call_data->extmove;
1228     CARD16 connect_id = call_data->any.connect_id;
1229     CARD16 input_method_ID;
1230
1231     fm = FrameMgrInit (ext_move_fr,
1232                        (char *) p,
1233                        _Xi18nNeedSwap (i18n_core, connect_id));
1234     /* get data */
1235     FrameMgrGetToken (fm, input_method_ID);
1236     FrameMgrGetToken (fm, extmove->icid);
1237     FrameMgrGetToken (fm, extmove->x);
1238     FrameMgrGetToken (fm, extmove->y);
1239
1240     FrameMgrFree (fm);
1241
1242     if (i18n_core->address.improto)
1243     {
1244         if (!(i18n_core->address.improto (ims, call_data)))
1245             return;
1246         /*endif*/
1247     }
1248     /*endif*/
1249 }
1250
1251 static void ExtensionMessageProc (XIMS ims,
1252                                   IMProtocol *call_data,
1253                                   unsigned char *p)
1254 {
1255     switch (call_data->any.minor_code)
1256     {
1257     case XIM_EXT_FORWARD_KEYEVENT:
1258         ExtForwardKeyEventMessageProc (ims, call_data, p);
1259         break;
1260
1261     case XIM_EXT_MOVE:
1262         ExtMoveMessageProc (ims, call_data, p);
1263         break;
1264     }
1265     /*endswitch*/
1266 }
1267
1268 static void TriggerNotifyMessageProc (XIMS ims,
1269                                       IMProtocol *call_data,
1270                                       unsigned char *p)
1271 {
1272     Xi18n i18n_core = ims->protocol;
1273     FrameMgr fm;
1274     extern XimFrameRec trigger_notify_fr[], trigger_notify_reply_fr[];
1275     register int total_size;
1276     unsigned char *reply = NULL;
1277     IMTriggerNotifyStruct *trigger =
1278         (IMTriggerNotifyStruct *) &call_data->triggernotify;
1279     CARD16 connect_id = call_data->any.connect_id;
1280     CARD16 input_method_ID;
1281     CARD32 flag;
1282
1283     fm = FrameMgrInit (trigger_notify_fr,
1284                        (char *) p,
1285                        _Xi18nNeedSwap (i18n_core, connect_id));
1286     /* get data */
1287     FrameMgrGetToken (fm, input_method_ID);
1288     FrameMgrGetToken (fm, trigger->icid);
1289     FrameMgrGetToken (fm, trigger->flag);
1290     FrameMgrGetToken (fm, trigger->key_index);
1291     FrameMgrGetToken (fm, trigger->event_mask);
1292     /*
1293       In order to support Front End Method, this event_mask must be saved
1294       per clients so that it should be restored by an XIM_EXT_SET_EVENT_MASK
1295       call when preediting mode is reset to off.
1296      */
1297
1298     flag = trigger->flag;
1299
1300     FrameMgrFree (fm);
1301
1302     fm = FrameMgrInit (trigger_notify_reply_fr,
1303                        NULL,
1304                        _Xi18nNeedSwap (i18n_core, connect_id));
1305  
1306     total_size = FrameMgrGetTotalSize (fm);
1307     reply = (unsigned char *) malloc (total_size);
1308     if (!reply)
1309     {
1310         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1311         return;
1312     }
1313     /*endif*/
1314     memset (reply, 0, total_size);
1315     FrameMgrSetBuffer (fm, reply);
1316
1317     FrameMgrPutToken (fm, input_method_ID);
1318     FrameMgrPutToken (fm, trigger->icid);
1319
1320     /* NOTE:
1321        XIM_TRIGGER_NOTIFY_REPLY should be sent before XIM_SET_EVENT_MASK
1322        in case of XIM_TRIGGER_NOTIFY(flag == ON), while it should be
1323        sent after XIM_SET_EVENT_MASK in case of
1324        XIM_TRIGGER_NOTIFY(flag == OFF).
1325        */
1326     if (flag == 0)
1327     {
1328         /* on key */
1329         _Xi18nSendMessage (ims,
1330                            connect_id,
1331                            XIM_TRIGGER_NOTIFY_REPLY,
1332                            0,
1333                            reply,
1334                            total_size);
1335         IMPreeditStart (ims, (XPointer)call_data);
1336     }
1337     /*endif*/
1338     if (i18n_core->address.improto)
1339     {
1340         if (!(i18n_core->address.improto(ims, call_data)))
1341             return;
1342         /*endif*/
1343     }
1344     /*endif*/
1345
1346     if (flag == 1)
1347     {
1348         /* off key */
1349         IMPreeditEnd (ims, (XPointer) call_data);
1350         _Xi18nSendMessage (ims,
1351                            connect_id,
1352                            XIM_TRIGGER_NOTIFY_REPLY,
1353                            0,
1354                            reply,
1355                            total_size);
1356     }
1357     /*endif*/
1358     FrameMgrFree (fm);
1359     XFree (reply);
1360 }
1361
1362 static INT16 ChooseEncoding (Xi18n i18n_core,
1363                              IMEncodingNegotiationStruct *enc_nego)
1364 {
1365     Xi18nAddressRec *address = (Xi18nAddressRec *) & i18n_core->address;
1366     XIMEncodings *p;
1367     int i, j;
1368     int enc_index=0;
1369
1370     p = (XIMEncodings *) &address->encoding_list;
1371     for (i = 0;  i < (int) p->count_encodings;  i++)
1372     {
1373         for (j = 0;  j < (int) enc_nego->encoding_number;  j++)
1374         {
1375             if (strcmp (p->supported_encodings[i],
1376                         enc_nego->encoding[j].name) == 0)
1377             {
1378                 enc_index = j;
1379                 break;
1380             }
1381             /*endif*/
1382         }
1383         /*endfor*/
1384     }
1385     /*endfor*/
1386
1387     return (INT16) enc_index;
1388 #if 0
1389     return (INT16) XIM_Default_Encoding_IDX;
1390 #endif
1391 }
1392
1393 static void EncodingNegotiatonMessageProc (XIMS ims,
1394                                            IMProtocol *call_data,
1395                                            unsigned char *p)
1396 {
1397     Xi18n i18n_core = ims->protocol;
1398     FrameMgr fm;
1399     FmStatus status;
1400     CARD16 byte_length;
1401     extern XimFrameRec encoding_negotiation_fr[];
1402     extern XimFrameRec encoding_negotiation_reply_fr[];
1403     register int i, total_size;
1404     unsigned char *reply = NULL;
1405     IMEncodingNegotiationStruct *enc_nego =
1406         (IMEncodingNegotiationStruct *) &call_data->encodingnego;
1407     CARD16 connect_id = call_data->any.connect_id;
1408     CARD16 input_method_ID;
1409
1410     fm = FrameMgrInit (encoding_negotiation_fr,
1411                        (char *) p,
1412                        _Xi18nNeedSwap (i18n_core, connect_id));
1413
1414     FrameMgrGetToken (fm, input_method_ID);
1415
1416     /* get ENCODING STR field */
1417     FrameMgrGetToken (fm, byte_length);
1418     if (byte_length > 0)
1419     {
1420         enc_nego->encoding = (XIMStr *) malloc (sizeof (XIMStr)*10);
1421         memset (enc_nego->encoding, 0, sizeof (XIMStr)*10);
1422         i = 0;
1423         while (FrameMgrIsIterLoopEnd (fm, &status) == False)
1424         {
1425             char *name;
1426             int str_length;
1427             
1428             FrameMgrGetToken (fm, str_length);
1429             FrameMgrSetSize (fm, str_length);
1430             enc_nego->encoding[i].length = str_length;
1431             FrameMgrGetToken (fm, name);
1432             enc_nego->encoding[i].name = malloc (str_length + 1);
1433             strncpy (enc_nego->encoding[i].name, name, str_length);
1434             enc_nego->encoding[i].name[str_length] = '\0';
1435             i++;
1436         }
1437         /*endwhile*/
1438         enc_nego->encoding_number = i;
1439     }
1440     /*endif*/
1441     /* get ENCODING INFO field */
1442     FrameMgrGetToken (fm, byte_length);
1443     if (byte_length > 0)
1444     {
1445         enc_nego->encodinginfo = (XIMStr *) malloc (sizeof (XIMStr)*10);
1446         memset (enc_nego->encoding, 0, sizeof (XIMStr)*10);
1447         i = 0;
1448         while (FrameMgrIsIterLoopEnd (fm, &status) == False)
1449         {
1450             char *name;
1451             int str_length;
1452             
1453             FrameMgrGetToken (fm, str_length);
1454             FrameMgrSetSize (fm, str_length);
1455             enc_nego->encodinginfo[i].length = str_length;
1456             FrameMgrGetToken (fm, name);
1457             enc_nego->encodinginfo[i].name = malloc (str_length + 1);
1458             strncpy (enc_nego->encodinginfo[i].name, name, str_length);
1459             enc_nego->encodinginfo[i].name[str_length] = '\0';
1460             i++;
1461         }
1462         /*endwhile*/
1463         enc_nego->encoding_info_number = i;
1464     }
1465     /*endif*/
1466
1467     enc_nego->enc_index = ChooseEncoding (i18n_core, enc_nego);
1468     enc_nego->category = 0;
1469
1470 #ifdef PROTOCOL_RICH
1471     if (i18n_core->address.improto)
1472     {
1473         if (!(i18n_core->address.improto(ims, call_data)))
1474             return;
1475         /*endif*/
1476     }
1477     /*endif*/
1478 #endif  /* PROTOCOL_RICH */
1479
1480     FrameMgrFree (fm);
1481
1482     fm = FrameMgrInit (encoding_negotiation_reply_fr,
1483                        NULL,
1484                        _Xi18nNeedSwap (i18n_core, connect_id));
1485
1486     total_size = FrameMgrGetTotalSize (fm);
1487     reply = (unsigned char *) malloc (total_size);
1488     if (!reply)
1489     {
1490         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1491         return;
1492     }
1493     /*endif*/
1494     memset (reply, 0, total_size);
1495     FrameMgrSetBuffer (fm, reply);
1496
1497     FrameMgrPutToken (fm, input_method_ID);
1498     FrameMgrPutToken (fm, enc_nego->category);
1499     FrameMgrPutToken (fm, enc_nego->enc_index);
1500
1501     _Xi18nSendMessage (ims,
1502                        connect_id,
1503                        XIM_ENCODING_NEGOTIATION_REPLY,
1504                        0,
1505                        reply,
1506                        total_size);
1507     XFree (reply);
1508
1509     /* free data for encoding list */
1510     if (enc_nego->encoding)
1511     {
1512         for (i = 0;  i < (int) enc_nego->encoding_number;  i++)
1513             XFree (enc_nego->encoding[i].name);
1514         /*endfor*/
1515         XFree (enc_nego->encoding);
1516     }
1517     /*endif*/
1518     if (enc_nego->encodinginfo)
1519     {
1520         for (i = 0;  i < (int) enc_nego->encoding_info_number;  i++)
1521             XFree (enc_nego->encodinginfo[i].name);
1522         /*endfor*/
1523         XFree (enc_nego->encodinginfo);
1524     }
1525     /*endif*/
1526     FrameMgrFree (fm);
1527 }
1528
1529 void PreeditStartReplyMessageProc (XIMS ims,
1530                                    IMProtocol *call_data,
1531                                    unsigned char *p)
1532 {
1533     Xi18n i18n_core = ims->protocol;
1534     FrameMgr fm;
1535     extern XimFrameRec preedit_start_reply_fr[];
1536     IMPreeditCBStruct *preedit_CB =
1537         (IMPreeditCBStruct *) &call_data->preedit_callback;
1538     CARD16 connect_id = call_data->any.connect_id;
1539     CARD16 input_method_ID;
1540
1541     fm = FrameMgrInit (preedit_start_reply_fr,
1542                        (char *) p,
1543                        _Xi18nNeedSwap (i18n_core, connect_id));
1544     /* get data */
1545     FrameMgrGetToken (fm, input_method_ID);
1546     FrameMgrGetToken (fm, preedit_CB->icid);
1547     FrameMgrGetToken (fm, preedit_CB->todo.return_value);
1548
1549     FrameMgrFree (fm);
1550
1551     if (i18n_core->address.improto)
1552     {
1553         if (!(i18n_core->address.improto (ims, call_data)))
1554             return;
1555         /*endif*/
1556     }
1557     /*endif*/
1558 }
1559
1560 void PreeditCaretReplyMessageProc (XIMS ims,
1561                                    IMProtocol *call_data,
1562                                    unsigned char *p)
1563 {
1564     Xi18n i18n_core = ims->protocol;
1565     FrameMgr fm;
1566     extern XimFrameRec preedit_caret_reply_fr[];
1567     IMPreeditCBStruct *preedit_CB =
1568         (IMPreeditCBStruct *) &call_data->preedit_callback;
1569     XIMPreeditCaretCallbackStruct *caret =
1570         (XIMPreeditCaretCallbackStruct *) & preedit_CB->todo.caret;
1571     CARD16 connect_id = call_data->any.connect_id;
1572     CARD16 input_method_ID;
1573
1574     fm = FrameMgrInit (preedit_caret_reply_fr,
1575                        (char *) p,
1576                        _Xi18nNeedSwap (i18n_core, connect_id));
1577     /* get data */
1578     FrameMgrGetToken (fm, input_method_ID);
1579     FrameMgrGetToken (fm, preedit_CB->icid);
1580     FrameMgrGetToken (fm, caret->position);
1581
1582     FrameMgrFree (fm);
1583
1584     if (i18n_core->address.improto)
1585     {
1586         if (!(i18n_core->address.improto(ims, call_data)))
1587             return;
1588         /*endif*/
1589     }
1590     /*endif*/
1591 }
1592
1593 void StrConvReplyMessageProc (XIMS ims,
1594                               IMProtocol *call_data,
1595                               unsigned char *p)
1596 {
1597     return;
1598 }
1599
1600 static void AddQueue (Xi18nClient *client, unsigned char *p)
1601 {
1602     XIMPending *new;
1603     XIMPending *last;
1604
1605     if ((new = (XIMPending *) malloc (sizeof (XIMPending))) == NULL)
1606         return;
1607     /*endif*/
1608     new->p = p;
1609     new->next = (XIMPending *) NULL;
1610     if (!client->pending)
1611     {
1612         client->pending = new;
1613     }
1614     else
1615     {
1616         for (last = client->pending;  last->next;  last = last->next)
1617             ;
1618         /*endfor*/
1619         last->next = new;
1620     }
1621     /*endif*/
1622     return;
1623 }
1624
1625 static void ProcessQueue (XIMS ims, CARD16 connect_id)
1626 {
1627     Xi18n i18n_core = ims->protocol;
1628     Xi18nClient *client = (Xi18nClient *) _Xi18nFindClient (i18n_core,
1629                                                             connect_id);
1630
1631     while (client->sync == False  &&  client->pending)
1632     {
1633         XimProtoHdr *hdr = (XimProtoHdr *) client->pending->p;
1634         unsigned char *p1 = (unsigned char *) (hdr + 1);
1635         IMProtocol call_data;
1636
1637         call_data.major_code = hdr->major_opcode;
1638         call_data.any.minor_code = hdr->minor_opcode;
1639         call_data.any.connect_id = connect_id;
1640
1641         switch (hdr->major_opcode)
1642         {
1643         case XIM_FORWARD_EVENT:
1644             ForwardEventMessageProc(ims, &call_data, p1);
1645             break;
1646         }
1647         /*endswitch*/
1648         XFree (hdr);
1649         {
1650             XIMPending *old = client->pending;
1651
1652             client->pending = old->next;
1653             XFree (old);
1654         }
1655     }
1656     /*endwhile*/
1657     return;
1658 }
1659
1660
1661 void _Xi18nMessageHandler (XIMS ims,
1662                            CARD16 connect_id,
1663                            unsigned char *p,
1664                            Bool *delete)
1665 {
1666     XimProtoHdr *hdr = (XimProtoHdr *)p;
1667     unsigned char *p1 = (unsigned char *)(hdr + 1);
1668     IMProtocol call_data;
1669     Xi18n i18n_core = ims->protocol;
1670     Xi18nClient *client;
1671
1672     client = (Xi18nClient *) _Xi18nFindClient (i18n_core, connect_id);
1673     if (hdr == (XimProtoHdr *) NULL)
1674         return;
1675     /*endif*/
1676     
1677     memset (&call_data, 0, sizeof(IMProtocol));
1678
1679     call_data.major_code = hdr->major_opcode;
1680     call_data.any.minor_code = hdr->minor_opcode;
1681     call_data.any.connect_id = connect_id;
1682
1683     switch (call_data.major_code)
1684     {
1685     case XIM_CONNECT:
1686 #ifdef XIM_DEBUG
1687         DebugLog("-- XIM_CONNECT\n");
1688 #endif
1689         ConnectMessageProc (ims, &call_data, p1);
1690         break;
1691
1692     case XIM_DISCONNECT:
1693 #ifdef XIM_DEBUG
1694         DebugLog("-- XIM_DISCONNECT\n");
1695 #endif
1696         DisConnectMessageProc (ims, &call_data);
1697         break;
1698
1699     case XIM_OPEN:
1700 #ifdef XIM_DEBUG
1701         DebugLog("-- XIM_OPEN\n");
1702 #endif
1703         OpenMessageProc (ims, &call_data, p1);
1704         break;
1705
1706     case XIM_CLOSE:
1707 #ifdef XIM_DEBUG
1708         DebugLog("-- XIM_CLOSE\n");
1709 #endif
1710         CloseMessageProc (ims, &call_data, p1);
1711         break;
1712
1713     case XIM_QUERY_EXTENSION:
1714 #ifdef XIM_DEBUG
1715         DebugLog("-- XIM_QUERY_EXTENSION\n");
1716 #endif
1717         QueryExtensionMessageProc (ims, &call_data, p1);
1718         break;
1719
1720     case XIM_GET_IM_VALUES:
1721 #ifdef XIM_DEBUG
1722         DebugLog("-- XIM_GET_IM_VALUES\n");
1723 #endif
1724         GetIMValuesMessageProc (ims, &call_data, p1);
1725         break;
1726
1727     case XIM_CREATE_IC:
1728 #ifdef XIM_DEBUG
1729         DebugLog("-- XIM_CREATE_IC\n");
1730 #endif
1731         CreateICMessageProc (ims, &call_data, p1);
1732         break;
1733
1734     case XIM_SET_IC_VALUES:
1735 #ifdef XIM_DEBUG
1736         DebugLog("-- XIM_SET_IC_VALUES\n");
1737 #endif
1738         SetICValuesMessageProc (ims, &call_data, p1);
1739         break;
1740
1741     case XIM_GET_IC_VALUES:
1742 #ifdef XIM_DEBUG
1743         DebugLog("-- XIM_GET_IC_VALUES\n");
1744 #endif
1745         GetICValuesMessageProc (ims, &call_data, p1);
1746         break;
1747
1748     case XIM_SET_IC_FOCUS:
1749 #ifdef XIM_DEBUG
1750         DebugLog("-- XIM_SET_IC_FOCUS\n");
1751 #endif
1752         SetICFocusMessageProc (ims, &call_data, p1);
1753         break;
1754
1755     case XIM_UNSET_IC_FOCUS:
1756 #ifdef XIM_DEBUG
1757         DebugLog("-- XIM_UNSET_IC_FOCUS\n");
1758 #endif
1759         UnsetICFocusMessageProc (ims, &call_data, p1);
1760         break;
1761
1762     case XIM_DESTROY_IC:
1763 #ifdef XIM_DEBUG
1764         DebugLog("-- XIM_DESTROY_IC\n");
1765 #endif
1766         DestroyICMessageProc (ims, &call_data, p1);
1767         break;
1768
1769     case XIM_RESET_IC:
1770 #ifdef XIM_DEBUG
1771         DebugLog("-- XIM_RESET_IC\n");
1772 #endif
1773         ResetICMessageProc (ims, &call_data, p1);
1774         break;
1775
1776     case XIM_FORWARD_EVENT:
1777 #ifdef XIM_DEBUG
1778         DebugLog("-- XIM_FORWARD_EVENT\n");
1779 #endif
1780         if (client->sync == True)
1781         {
1782             AddQueue (client, p);
1783             *delete = False;
1784         }
1785         else
1786         {
1787             ForwardEventMessageProc (ims, &call_data, p1);
1788         }
1789         break;
1790
1791     case XIM_EXTENSION:
1792 #ifdef XIM_DEBUG
1793         DebugLog("-- XIM_EXTENSION\n");
1794 #endif
1795         ExtensionMessageProc (ims, &call_data, p1);
1796         break;
1797
1798     case XIM_SYNC:
1799 #ifdef XIM_DEBUG
1800         DebugLog("-- XIM_SYNC\n");
1801 #endif
1802         break;
1803
1804     case XIM_SYNC_REPLY:
1805 #ifdef XIM_DEBUG
1806         DebugLog("-- XIM_SYNC_REPLY\n");
1807 #endif
1808         SyncReplyMessageProc (ims, &call_data, p1);
1809         ProcessQueue (ims, connect_id);
1810         break;
1811
1812     case XIM_TRIGGER_NOTIFY:
1813 #ifdef XIM_DEBUG
1814         DebugLog("-- XIM_TRIGGER_NOTIFY\n");
1815 #endif
1816         TriggerNotifyMessageProc (ims, &call_data, p1);
1817         break;
1818
1819     case XIM_ENCODING_NEGOTIATION:
1820 #ifdef XIM_DEBUG
1821         DebugLog("-- XIM_ENCODING_NEGOTIATION\n");
1822 #endif
1823         EncodingNegotiatonMessageProc (ims, &call_data, p1);
1824         break;
1825
1826     case XIM_PREEDIT_START_REPLY:
1827 #ifdef XIM_DEBUG
1828         DebugLog("-- XIM_PREEDIT_START_REPLY\n");
1829 #endif
1830         PreeditStartReplyMessageProc (ims, &call_data, p1);
1831         break;
1832
1833     case XIM_PREEDIT_CARET_REPLY:
1834 #ifdef XIM_DEBUG
1835         DebugLog("-- XIM_PREEDIT_CARET_REPLY\n");
1836 #endif
1837         PreeditCaretReplyMessageProc (ims, &call_data, p1);
1838         break;
1839
1840     case XIM_STR_CONVERSION_REPLY:
1841 #ifdef XIM_DEBUG
1842         DebugLog("-- XIM_STR_CONVERSION_REPLY\n");
1843 #endif
1844         StrConvReplyMessageProc (ims, &call_data, p1);
1845         break;
1846     }
1847     /*endswitch*/
1848 }