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