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