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