upload tizen2.0 source
[framework/uifw/xorg/lib/libx11.git] / modules / im / ximcp / imDefLkup.c
1 /******************************************************************
2
3            Copyright 1992, 1993, 1994 by FUJITSU LIMITED
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and
8 that both that copyright notice and this permission notice appear
9 in supporting documentation, and that the name of FUJITSU LIMITED
10 not be used in advertising or publicity pertaining to distribution
11 of the software without specific, written prior permission.
12 FUJITSU LIMITED makes no representations about the suitability of
13 this software for any purpose.
14 It is provided "as is" without express or implied warranty.
15
16 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 PERFORMANCE OF THIS SOFTWARE.
23
24   Author: Takashi Fujiwara     FUJITSU LIMITED
25                                fujiwara@a80.tech.yk.fujitsu.co.jp
26
27 ******************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include <X11/Xatom.h>
33 #include "Xlibint.h"
34 #include "Xlcint.h"
35 #include "Ximint.h"
36
37 Public Xic
38 _XimICOfXICID(
39     Xim           im,
40     XICID         icid)
41 {
42     Xic           pic;
43
44     for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) {
45         if (pic->private.proto.icid == icid)
46             return pic;
47     }
48     return (Xic)0;
49 }
50
51 Private void
52 _XimProcIMSetEventMask(
53     Xim          im,
54     XPointer     buf)
55 {
56     EVENTMASK   *buf_l = (EVENTMASK *)buf;
57
58     im->private.proto.forward_event_mask     = buf_l[0];
59     im->private.proto.synchronous_event_mask = buf_l[1];
60     return;
61 }
62
63 Private void
64 _XimProcICSetEventMask(
65     Xic          ic,
66     XPointer     buf)
67 {
68     EVENTMASK   *buf_l = (EVENTMASK *)buf;
69
70     ic->private.proto.forward_event_mask     = buf_l[0];
71     ic->private.proto.synchronous_event_mask = buf_l[1];
72     _XimReregisterFilter(ic);
73     return;
74 }
75
76 Public Bool
77 _XimSetEventMaskCallback(
78     Xim          xim,
79     INT16        len,
80     XPointer     data,
81     XPointer     call_data)
82 {
83     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
84     XIMID        imid = buf_s[0];
85     XICID        icid = buf_s[1];
86     Xim          im = (Xim)call_data;
87     Xic          ic;
88
89     if (imid == im->private.proto.imid) {
90         if (icid) {
91             ic = _XimICOfXICID(im, icid);
92             _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]);
93         } else {
94             _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]);
95         }
96         return True;
97     }
98     return False;
99 }
100
101 Private Bool
102 _XimSyncCheck(
103     Xim          im,
104     INT16        len,
105     XPointer     data,
106     XPointer     arg)
107 {
108     Xic          ic  = (Xic)arg;
109     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
110     CARD8        major_opcode = *((CARD8 *)data);
111     CARD8        minor_opcode = *((CARD8 *)data + 1);
112     XIMID        imid = buf_s[0];
113     XICID        icid = buf_s[1];
114
115     if ((major_opcode == XIM_SYNC_REPLY)
116      && (minor_opcode == 0)
117      && (imid == im->private.proto.imid)
118      && (icid == ic->private.proto.icid))
119         return True;
120     if ((major_opcode == XIM_ERROR)
121      && (minor_opcode == 0)
122      && (buf_s[2] & XIM_IMID_VALID)
123      && (imid == im->private.proto.imid)
124      && (buf_s[2] & XIM_ICID_VALID)
125      && (icid == ic->private.proto.icid))
126         return True;
127     return False;
128 }
129
130 Public Bool
131 _XimSync(
132     Xim          im,
133     Xic          ic)
134 {
135     CARD32       buf32[BUFSIZE/4];
136     CARD8       *buf = (CARD8 *)buf32;
137     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
138     INT16        len;
139     CARD32       reply32[BUFSIZE/4];
140     char        *reply = (char *)reply32;
141     XPointer     preply;
142     int          buf_size;
143     int          ret_code;
144
145     buf_s[0] = im->private.proto.imid;          /* imid */
146     buf_s[1] = ic->private.proto.icid;          /* icid */
147
148     len = sizeof(CARD16)                        /* sizeof imid */
149         + sizeof(CARD16);                       /* sizeof icid */
150
151     _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len);
152     if (!(_XimWrite(im, len, (XPointer)buf)))
153         return False;
154     _XimFlush(im);
155     buf_size = BUFSIZE;
156     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
157                                         _XimSyncCheck, (XPointer)ic);
158     if(ret_code == XIM_TRUE) {
159         preply = reply;
160     } else if(ret_code == XIM_OVERFLOW) {
161         if(len <= 0) {
162             preply = reply;
163         } else {
164             buf_size = len;
165             preply = (XPointer)Xmalloc(len);
166             ret_code = _XimRead(im, &len, preply, buf_size,
167                                         _XimSyncCheck, (XPointer)ic);
168             if(ret_code != XIM_TRUE) {
169                 Xfree(preply);
170                 return False;
171             }
172         }
173     } else {
174         return False;
175     }
176     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
177     if (*((CARD8 *)preply) == XIM_ERROR) {
178         _XimProcError(im, 0, (XPointer)&buf_s[3]);
179         if(reply != preply)
180             Xfree(preply);
181         return False;
182     }
183     if(reply != preply)
184         Xfree(preply);
185     return True;
186 }
187
188 Public Bool
189 _XimProcSyncReply(
190     Xim          im,
191     Xic          ic)
192 {
193     CARD32       buf32[BUFSIZE/4];
194     CARD8       *buf = (CARD8 *)buf32;
195     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
196     INT16        len;
197
198     buf_s[0] = im->private.proto.imid;          /* imid */
199     buf_s[1] = ic->private.proto.icid;          /* icid */
200
201     len = sizeof(CARD16)                        /* sizeof imid */
202         + sizeof(CARD16);                       /* sizeof icid */
203
204     _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len);
205     if (!(_XimWrite(im, len, (XPointer)buf)))
206         return False;
207     _XimFlush(im);
208     return True;
209 }
210
211 Public Bool
212 _XimRespSyncReply(
213     Xic          ic,
214     BITMASK16    mode)
215 {
216     if (mode & XimSYNCHRONUS) /* SYNC Request */
217         MARK_NEED_SYNC_REPLY(ic->core.im);
218
219     return True;
220 }
221
222 Public Bool
223 _XimSyncCallback(
224     Xim          xim,
225     INT16        len,
226     XPointer     data,
227     XPointer     call_data)
228 {
229     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
230     XIMID        imid = buf_s[0];
231     XICID        icid = buf_s[1];
232     Xim          im = (Xim)call_data;
233     Xic          ic;
234
235     if ((imid == im->private.proto.imid)
236      && (ic = _XimICOfXICID(im, icid))) {
237         (void)_XimProcSyncReply(im, ic);
238         return True;
239     }
240     return False;
241 }
242
243 Private INT16
244 _XimSetEventToWire(
245     XEvent      *ev,
246     xEvent      *event)
247 {
248     if (!(_XimProtoEventToWire(ev, event, False)))
249         return 0;
250     event->u.u.sequenceNumber =
251                 ((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
252     return sz_xEvent;
253 }
254
255 Private Bool
256 _XimForwardEventCore(
257     Xic          ic,
258     XEvent      *ev,
259     Bool         sync)
260 {
261     Xim          im = (Xim)ic->core.im;
262     CARD32       buf32[BUFSIZE/4];
263     CARD8       *buf = (CARD8 *)buf32;
264     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
265     CARD32       reply32[BUFSIZE/4];
266     char        *reply = (char *)reply32;
267     XPointer     preply;
268     int          buf_size;
269     int          ret_code;
270     INT16        len;
271
272     if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
273         return False;                           /* X event */
274
275     buf_s[0] = im->private.proto.imid;          /* imid */
276     buf_s[1] = ic->private.proto.icid;          /* icid */
277     buf_s[2] = sync ? XimSYNCHRONUS : 0;        /* flag */
278     buf_s[3] =
279         (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
280                                                 /* serial number */
281
282     len += sizeof(CARD16)                       /* sizeof imid */
283          + sizeof(CARD16)                       /* sizeof icid */
284          + sizeof(BITMASK16)                    /* sizeof flag */
285          + sizeof(CARD16);                      /* sizeof serila number */
286
287     _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
288     if (!(_XimWrite(im, len, (XPointer)buf)))
289         return False;
290     _XimFlush(im);
291
292     if (sync) {
293         buf_size = BUFSIZE;
294         ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
295                                         _XimSyncCheck, (XPointer)ic);
296         if(ret_code == XIM_TRUE) {
297             preply = reply;
298         } else if(ret_code == XIM_OVERFLOW) {
299             if(len <= 0) {
300                 preply = reply;
301             } else {
302                 buf_size = len;
303                 preply = (XPointer)Xmalloc(len);
304                 ret_code = _XimRead(im, &len, preply, buf_size,
305                                         _XimSyncCheck, (XPointer)ic);
306                 if(ret_code != XIM_TRUE) {
307                     Xfree(preply);
308                     return False;
309                 }
310             }
311         } else {
312             return False;
313         }
314         buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
315         if (*((CARD8 *)preply) == XIM_ERROR) {
316             _XimProcError(im, 0, (XPointer)&buf_s[3]);
317             if(reply != preply)
318                 Xfree(preply);
319             return False;
320         }
321         if(reply != preply)
322             Xfree(preply);
323     }
324     return True;
325 }
326
327 Public Bool
328 _XimForwardEvent(
329     Xic          ic,
330     XEvent      *ev,
331     Bool         sync)
332 {
333 #ifdef EXT_FORWARD
334     if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
335         if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
336             return True;
337 #endif
338     return _XimForwardEventCore(ic, ev, sync);
339 }
340
341 Private void
342 _XimProcEvent(
343     Display             *d,
344     Xic                  ic,
345     XEvent              *ev,
346     CARD16              *buf)
347 {
348     INT16        serial = buf[0];
349     xEvent      *xev = (xEvent *)&buf[1];
350
351     _XimProtoWireToEvent(ev, xev, False);
352     ev->xany.serial |= serial << 16;
353     ev->xany.send_event = False;
354     ev->xany.display = d;
355     MARK_FABRICATED(ic->core.im);
356     return;
357 }
358
359 Private Bool
360 _XimForwardEventRecv(
361     Xim          im,
362     Xic          ic,
363     XPointer     buf)
364 {
365     CARD16      *buf_s = (CARD16 *)buf;
366     Display     *d = im->core.display;
367     XEvent       ev;
368
369     _XimProcEvent(d, ic, &ev, &buf_s[1]);
370
371     (void)_XimRespSyncReply(ic, buf_s[0]);
372
373     XPutBackEvent(d, &ev);
374
375     return True;
376 }
377
378 Public Bool
379 _XimForwardEventCallback(
380     Xim          xim,
381     INT16        len,
382     XPointer     data,
383     XPointer     call_data)
384 {
385     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
386     XIMID        imid = buf_s[0];
387     XICID        icid = buf_s[1];
388     Xim          im = (Xim)call_data;
389     Xic          ic;
390
391     if ((imid == im->private.proto.imid)
392      && (ic = _XimICOfXICID(im, icid))) {
393         (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
394         return True;
395     }
396     return False;
397 }
398
399 Private Bool
400 _XimRegisterTriggerkey(
401     Xim                  im,
402     XPointer             buf)
403 {
404     CARD32              *buf_l = (CARD32 *)buf;
405     CARD32               len;
406     CARD32              *key;
407
408     if (IS_DYNAMIC_EVENT_FLOW(im))      /* already Dynamic event flow mode */
409         return True;
410
411     /*
412      *  register onkeylist
413      */
414
415     len = buf_l[0];                             /* length of on-keys */
416     len += sizeof(INT32);                       /* sizeof length of on-keys */
417
418     if (!(key = (CARD32 *)Xmalloc(len))) {
419         _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
420         return False;
421     }
422     memcpy((char *)key, (char *)buf_l, len);
423     im->private.proto.im_onkeylist = key;
424
425     MARK_DYNAMIC_EVENT_FLOW(im);
426
427     /*
428      *  register offkeylist
429      */
430
431     buf_l = (CARD32 *)((char *)buf + len);
432     len = buf_l[0];                             /* length of off-keys */
433     len += sizeof(INT32);                       /* sizeof length of off-keys */
434
435     if (!(key = (CARD32 *)Xmalloc(len))) {
436         _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
437         return False;
438     }
439
440     memcpy((char *)key, (char *)buf_l, len);
441     im->private.proto.im_offkeylist = key;
442
443     return True;
444 }
445
446 Public Bool
447 _XimRegisterTriggerKeysCallback(
448     Xim          xim,
449     INT16        len,
450     XPointer     data,
451     XPointer     call_data)
452 {
453     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
454     Xim          im = (Xim)call_data;
455
456     (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
457     return True;
458 }
459
460 Public EVENTMASK
461 _XimGetWindowEventmask(
462     Xic          ic)
463 {
464     Xim                 im = (Xim )ic->core.im;
465     XWindowAttributes   atr;
466
467     if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
468         return 0;
469     return (EVENTMASK)atr.your_event_mask;
470 }
471
472
473 Private Bool
474 _XimTriggerNotifyCheck(
475     Xim          im,
476     INT16        len,
477     XPointer     data,
478     XPointer     arg)
479 {
480     Xic          ic  = (Xic)arg;
481     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
482     CARD8        major_opcode = *((CARD8 *)data);
483     CARD8        minor_opcode = *((CARD8 *)data + 1);
484     XIMID        imid = buf_s[0];
485     XICID        icid = buf_s[1];
486
487     if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
488      && (minor_opcode == 0)
489      && (imid == im->private.proto.imid)
490      && (icid == ic->private.proto.icid))
491         return True;
492     if ((major_opcode == XIM_ERROR)
493      && (minor_opcode == 0)
494      && (buf_s[2] & XIM_IMID_VALID)
495      && (imid == im->private.proto.imid)
496      && (buf_s[2] & XIM_ICID_VALID)
497      && (icid == ic->private.proto.icid))
498         return True;
499     return False;
500 }
501
502 Public Bool
503 _XimTriggerNotify(
504     Xim          im,
505     Xic          ic,
506     int          mode,
507     CARD32       idx)
508 {
509     CARD32       buf32[BUFSIZE/4];
510     CARD8       *buf = (CARD8 *)buf32;
511     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
512     CARD32      *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
513     CARD32       reply32[BUFSIZE/4];
514     char        *reply = (char *)reply32;
515     XPointer     preply;
516     int          buf_size;
517     int          ret_code;
518     INT16        len;
519     EVENTMASK    mask = _XimGetWindowEventmask(ic);
520
521     buf_s[0] = im->private.proto.imid;  /* imid */
522     buf_s[1] = ic->private.proto.icid;  /* icid */
523     buf_l[1] = mode;                    /* flag */
524     buf_l[2] = idx;                     /* index of keys list */
525     buf_l[3] = mask;                    /* select-event-mask */
526
527     len = sizeof(CARD16)                /* sizeof imid */
528         + sizeof(CARD16)                /* sizeof icid */
529         + sizeof(CARD32)                /* sizeof flag */
530         + sizeof(CARD32)                /* sizeof index of key list */
531         + sizeof(EVENTMASK);            /* sizeof select-event-mask */
532
533     _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
534     if (!(_XimWrite(im, len, (XPointer)buf)))
535         return False;
536     _XimFlush(im);
537     buf_size = BUFSIZE;
538     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
539                                 _XimTriggerNotifyCheck, (XPointer)ic);
540     if(ret_code == XIM_TRUE) {
541         preply = reply;
542     } else if(ret_code == XIM_OVERFLOW) {
543         if(len <= 0) {
544             preply = reply;
545         } else {
546             buf_size = len;
547             preply = (XPointer)Xmalloc(len);
548             ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
549                                 _XimTriggerNotifyCheck, (XPointer)ic);
550             if(ret_code != XIM_TRUE) {
551                 Xfree(preply);
552                 return False;
553             }
554         }
555     } else {
556         return False;
557     }
558     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
559     if (*((CARD8 *)preply) == XIM_ERROR) {
560         _XimProcError(im, 0, (XPointer)&buf_s[3]);
561         if(reply != preply)
562             Xfree(preply);
563         return False;
564     }
565     if(reply != preply)
566         Xfree(preply);
567     return True;
568 }
569
570 Private Bool
571 _XimRegCommitInfo(
572     Xic                  ic,
573     char                *string,
574     int                  string_len,
575     KeySym              *keysym,
576     int                  keysym_len)
577 {
578     XimCommitInfo       info;
579
580     if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec))))
581         return False;
582     info->string        = string;
583     info->string_len    = string_len;
584     info->keysym        = keysym;
585     info->keysym_len    = keysym_len;
586     info->next = ic->private.proto.commit_info;
587     ic->private.proto.commit_info = info;
588     return True;
589 }
590
591 Private void
592 _XimUnregCommitInfo(
593     Xic                 ic)
594 {
595     XimCommitInfo       info;
596
597     if (!(info = ic->private.proto.commit_info))
598         return;
599
600     if (info->string)
601         Xfree(info->string);
602     if (info->keysym)
603         Xfree(info->keysym);
604     ic->private.proto.commit_info = info->next;
605     Xfree(info);
606     return;
607 }
608
609 Public void
610 _XimFreeCommitInfo(
611     Xic                 ic)
612 {
613     while (ic->private.proto.commit_info)
614         _XimUnregCommitInfo(ic);
615     return;
616 }
617
618 Private Bool
619 _XimProcKeySym(
620     Xic                   ic,
621     CARD32                sym,
622     KeySym              **xim_keysym,
623     int                  *xim_keysym_len)
624 {
625     Xim                  im = (Xim)ic->core.im;
626
627     if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) {
628         _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
629         return False;
630     }
631
632     **xim_keysym = (KeySym)sym;
633     *xim_keysym_len = 1;
634
635     return True;
636 }
637
638 Private Bool
639 _XimProcCommit(
640     Xic           ic,
641     BYTE         *buf,
642     int           len,
643     char        **xim_string,
644     int          *xim_string_len)
645 {
646     Xim          im = (Xim)ic->core.im;
647     char        *string;
648
649     if (!(string = (char *)Xmalloc(len + 1))) {
650         _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
651         return False;
652     }
653
654     (void)memcpy(string, (char *)buf, len);
655     string[len] = '\0';
656
657     *xim_string = string;
658     *xim_string_len = len;
659     return True;
660 }
661
662 Private Bool
663 _XimCommitRecv(
664     Xim          im,
665     Xic          ic,
666     XPointer     buf)
667 {
668     CARD16      *buf_s = (CARD16 *)buf;
669     BITMASK16    flag = buf_s[0];
670     XKeyEvent    ev;
671     char        *string = NULL;
672     int          string_len = 0;
673     KeySym      *keysym = NULL;
674     int          keysym_len = 0;
675
676     if ((flag & XimLookupBoth) == XimLookupChars) {
677         if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
678                                         (int)buf_s[1], &string, &string_len)))
679             return False;
680
681     } else if ((flag & XimLookupBoth) == XimLookupKeySym) {
682         if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
683             return False;
684
685     } else if ((flag & XimLookupBoth) == XimLookupBoth) {
686         if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
687             return False;
688
689         if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
690                                         (int)buf_s[4], &string, &string_len))) {
691             Xfree(keysym);
692             return False;
693         }
694     }
695
696     if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
697         if (string)
698             Xfree(string);
699         if (keysym)
700             Xfree(keysym);
701         _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
702         return False;
703     }
704
705     (void)_XimRespSyncReply(ic, flag);
706
707     MARK_FABRICATED(im);
708
709     ev.type = KeyPress;
710     ev.send_event = False;
711     ev.display = im->core.display;
712     ev.window = ic->core.focus_window;
713     ev.keycode = 0;
714     ev.state = 0;
715
716     XPutBackEvent(im->core.display, (XEvent *)&ev);
717
718     return True;
719 }
720
721 Public Bool
722 _XimCommitCallback(
723     Xim          xim,
724     INT16        len,
725     XPointer     data,
726     XPointer     call_data)
727 {
728     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
729     XIMID        imid = buf_s[0];
730     XICID        icid = buf_s[1];
731     Xim          im = (Xim)call_data;
732     Xic          ic;
733
734     if ((imid == im->private.proto.imid)
735      && (ic = _XimICOfXICID(im, icid))) {
736         (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
737         return True;
738     }
739     return False;
740 }
741
742 Public void
743 _XimProcError(
744     Xim          im,
745     Xic          ic,
746     XPointer     data)
747 {
748     return;
749 }
750
751 Public Bool
752 _XimErrorCallback(
753     Xim          xim,
754     INT16        len,
755     XPointer     data,
756     XPointer     call_data)
757 {
758     CARD16      *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
759     BITMASK16    flag = buf_s[2];
760     XIMID        imid;
761     XICID        icid;
762     Xim          im = (Xim)call_data;
763     Xic          ic = NULL;
764
765     if (flag & XIM_IMID_VALID) {
766         imid = buf_s[0];
767         if (imid != im->private.proto.imid)
768             return False;
769     }
770     if (flag & XIM_ICID_VALID) {
771         icid = buf_s[1];
772         if (!(ic = _XimICOfXICID(im, icid)))
773             return False;
774     }
775     _XimProcError(im, ic, (XPointer)&buf_s[3]);
776
777     return True;
778 }
779
780 Public Bool
781 _XimError(
782     Xim          im,
783     Xic          ic,
784     CARD16       error_code,
785     INT16        detail_length,
786     CARD16       type,
787     char        *detail)
788 {
789     CARD32       buf32[BUFSIZE/4];
790     CARD8       *buf = (CARD8 *)buf32;
791     CARD16      *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
792     INT16        len = 0;
793
794     buf_s[0] = im->private.proto.imid;  /* imid */
795     buf_s[2] = XIM_IMID_VALID;          /* flag */
796     if (ic) {
797         buf_s[1] = ic->private.proto.icid;      /* icid */
798         buf_s[2] |= XIM_ICID_VALID;             /* flag */
799     }
800     buf_s[3] = error_code;                      /* Error Code */
801     buf_s[4] = detail_length;                   /* length of error detail */
802     buf_s[5] = type;                            /* type of error detail */
803
804     if (detail_length && detail) {
805         len = detail_length;
806         memcpy((char *)&buf_s[6], detail, len);
807         XIM_SET_PAD(&buf_s[6], len);
808     }
809
810     len += sizeof(CARD16)               /* sizeof imid */
811          + sizeof(CARD16)               /* sizeof icid */
812          + sizeof(BITMASK16)            /* sizeof flag */
813          + sizeof(CARD16)               /* sizeof error_code */
814          + sizeof(INT16)                /* sizeof length of detail */
815          + sizeof(CARD16);              /* sizeof type */
816
817     _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
818     if (!(_XimWrite(im, len, (XPointer)buf)))
819         return False;
820     _XimFlush(im);
821     return True;
822 }
823
824 Private int
825 _Ximctsconvert(
826     XlcConv      conv,
827     char        *from,
828     int          from_len,
829     char        *to,
830     int          to_len,
831     Status      *state)
832 {
833     int          from_left;
834     int          to_left;
835     int          from_savelen;
836     int          to_savelen;
837     int          from_cnvlen;
838     int          to_cnvlen;
839     char        *from_buf;
840     char        *to_buf;
841     char         scratchbuf[BUFSIZ];
842     Status       tmp_state;
843
844     if (!state)
845         state = &tmp_state;
846
847     if (!conv || !from || !from_len) {
848         *state = XLookupNone;
849         return 0;
850     }
851
852     /* Reset the converter.  The CompoundText at 'from' starts in
853        initial state.  */
854     _XlcResetConverter(conv);
855
856     from_left = from_len;
857     to_left = BUFSIZ;
858     from_cnvlen = 0;
859     to_cnvlen = 0;
860     for (;;) {
861         from_buf = &from[from_cnvlen];
862         from_savelen = from_left;
863         to_buf = &scratchbuf[to_cnvlen];
864         to_savelen = to_left;
865         if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
866                                  (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
867             *state = XLookupNone;
868             return 0;
869         }
870         from_cnvlen += (from_savelen - from_left);
871         to_cnvlen += (to_savelen - to_left);
872         if (from_left == 0) {
873             if (!to_cnvlen) {
874                 *state = XLookupNone;
875                 return 0;
876            }
877            break;
878         }
879     }
880
881     if (!to || !to_len || (to_len < to_cnvlen)) {
882        *state = XBufferOverflow;
883     } else {
884        memcpy(to, scratchbuf, to_cnvlen);
885        *state = XLookupChars;
886     }
887     return to_cnvlen;
888 }
889
890 Public int
891 _Ximctstombs(XIM xim, char *from, int from_len,
892              char *to, int to_len, Status *state)
893 {
894     return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
895                           from, from_len, to, to_len, state);
896 }
897
898 Public int
899 _Ximctstowcs(
900     XIM          xim,
901     char        *from,
902     int          from_len,
903     wchar_t     *to,
904     int          to_len,
905     Status      *state)
906 {
907     Xim          im = (Xim)xim;
908     XlcConv      conv = im->private.proto.ctow_conv;
909     int          from_left;
910     int          to_left;
911     int          from_savelen;
912     int          to_savelen;
913     int          from_cnvlen;
914     int          to_cnvlen;
915     char        *from_buf;
916     wchar_t     *to_buf;
917     wchar_t      scratchbuf[BUFSIZ];
918     Status       tmp_state;
919
920     if (!state)
921         state = &tmp_state;
922
923     if (!conv || !from || !from_len) {
924         *state = XLookupNone;
925         return 0;
926     }
927
928     /* Reset the converter.  The CompoundText at 'from' starts in
929        initial state.  */
930     _XlcResetConverter(conv);
931
932     from_left = from_len;
933     to_left = BUFSIZ;
934     from_cnvlen = 0;
935     to_cnvlen = 0;
936     for (;;) {
937         from_buf = &from[from_cnvlen];
938        from_savelen = from_left;
939        to_buf = &scratchbuf[to_cnvlen];
940        to_savelen = to_left;
941         if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
942                                  (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
943             *state = XLookupNone;
944             return 0;
945         }
946         from_cnvlen += (from_savelen - from_left);
947        to_cnvlen += (to_savelen - to_left);
948         if (from_left == 0) {
949            if (!to_cnvlen){
950                 *state = XLookupNone;
951                return 0;
952            }
953             break;
954         }
955     }
956
957     if (!to || !to_len || (to_len < to_cnvlen)) {
958        *state = XBufferOverflow;
959     } else {
960        memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
961        *state = XLookupChars;
962     }
963     return to_cnvlen;
964 }
965
966 Public int
967 _Ximctstoutf8(
968     XIM          xim,
969     char        *from,
970     int          from_len,
971     char        *to,
972     int          to_len,
973     Status      *state)
974 {
975     return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
976                           from, from_len, to, to_len, state);
977 }
978
979 Public int
980 _XimProtoMbLookupString(
981     XIC                  xic,
982     XKeyEvent           *ev,
983     char                *buffer,
984     int                  bytes,
985     KeySym              *keysym,
986     Status              *state)
987 {
988     Xic                  ic = (Xic)xic;
989     Xim                  im = (Xim)ic->core.im;
990     int                  ret;
991     Status               tmp_state;
992     XimCommitInfo        info;
993
994     if (!IS_SERVER_CONNECTED(im))
995         return 0;
996
997     if (!state)
998         state = &tmp_state;
999
1000     if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */
1001         if (!(info = ic->private.proto.commit_info)) {
1002             *state = XLookupNone;
1003             return 0;
1004         }
1005
1006         ret = im->methods->ctstombs((XIM)im, info->string,
1007                                 info->string_len, buffer, bytes, state);
1008         if (*state == XBufferOverflow)
1009             return ret;
1010         if (keysym && (info->keysym && *(info->keysym))) {
1011             *keysym = *(info->keysym);
1012             if (*state == XLookupChars)
1013                 *state = XLookupBoth;
1014             else
1015                 *state = XLookupKeySym;
1016         }
1017         _XimUnregCommitInfo(ic);
1018
1019     } else  if (ev->type == KeyPress) {
1020         ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
1021         if (ret > 0) {
1022            if (ret > bytes)
1023                *state = XBufferOverflow;
1024            else if (keysym && *keysym != NoSymbol)
1025                 *state = XLookupBoth;
1026             else
1027                 *state = XLookupChars;
1028         } else {
1029             if (keysym && *keysym != NoSymbol)
1030                 *state = XLookupKeySym;
1031             else
1032                 *state = XLookupNone;
1033         }
1034     } else {
1035         *state = XLookupNone;
1036         ret = 0;
1037     }
1038
1039     return ret;
1040 }
1041
1042 Public int
1043 _XimProtoWcLookupString(
1044     XIC                  xic,
1045     XKeyEvent           *ev,
1046     wchar_t             *buffer,
1047     int                  bytes,
1048     KeySym              *keysym,
1049     Status              *state)
1050 {
1051     Xic                  ic = (Xic)xic;
1052     Xim                  im = (Xim)ic->core.im;
1053     int                  ret;
1054     Status               tmp_state;
1055     XimCommitInfo        info;
1056
1057     if (!IS_SERVER_CONNECTED(im))
1058         return 0;
1059
1060     if (!state)
1061         state = &tmp_state;
1062
1063     if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
1064         if (!(info = ic->private.proto.commit_info)) {
1065            *state = XLookupNone;
1066             return 0;
1067         }
1068
1069         ret = im->methods->ctstowcs((XIM)im, info->string,
1070                                 info->string_len, buffer, bytes, state);
1071         if (*state == XBufferOverflow)
1072            return ret;
1073         if (keysym && (info->keysym && *(info->keysym))) {
1074             *keysym = *(info->keysym);
1075             if (*state == XLookupChars)
1076                 *state = XLookupBoth;
1077             else
1078                 *state = XLookupKeySym;
1079         }
1080         _XimUnregCommitInfo(ic);
1081
1082     } else if (ev->type == KeyPress) {
1083         ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
1084         if (ret > 0) {
1085            if (ret > bytes)
1086                *state = XBufferOverflow;
1087            else if (keysym && *keysym != NoSymbol)
1088                 *state = XLookupBoth;
1089             else
1090                 *state = XLookupChars;
1091         } else {
1092             if (keysym && *keysym != NoSymbol)
1093                 *state = XLookupKeySym;
1094             else
1095                 *state = XLookupNone;
1096         }
1097     } else {
1098         *state = XLookupNone;
1099         ret = 0;
1100     }
1101
1102     return ret;
1103 }
1104
1105 Public int
1106 _XimProtoUtf8LookupString(
1107     XIC                  xic,
1108     XKeyEvent           *ev,
1109     char                *buffer,
1110     int                  bytes,
1111     KeySym              *keysym,
1112     Status              *state)
1113 {
1114     Xic                  ic = (Xic)xic;
1115     Xim                  im = (Xim)ic->core.im;
1116     int                  ret;
1117     Status               tmp_state;
1118     XimCommitInfo        info;
1119
1120     if (!IS_SERVER_CONNECTED(im))
1121         return 0;
1122
1123     if (!state)
1124         state = &tmp_state;
1125
1126     if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
1127         if (!(info = ic->private.proto.commit_info)) {
1128            *state = XLookupNone;
1129             return 0;
1130         }
1131
1132         ret = im->methods->ctstoutf8((XIM)im, info->string,
1133                                 info->string_len, buffer, bytes, state);
1134         if (*state == XBufferOverflow)
1135            return ret;
1136         if (keysym && (info->keysym && *(info->keysym))) {
1137             *keysym = *(info->keysym);
1138             if (*state == XLookupChars)
1139                 *state = XLookupBoth;
1140             else
1141                 *state = XLookupKeySym;
1142         }
1143         _XimUnregCommitInfo(ic);
1144
1145     } else if (ev->type == KeyPress) {
1146         ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
1147         if (ret > 0) {
1148            if (ret > bytes)
1149                *state = XBufferOverflow;
1150            else if (keysym && *keysym != NoSymbol)
1151                 *state = XLookupBoth;
1152             else
1153                 *state = XLookupChars;
1154         } else {
1155             if (keysym && *keysym != NoSymbol)
1156                 *state = XLookupKeySym;
1157             else
1158                 *state = XLookupNone;
1159         }
1160     } else {
1161         *state = XLookupNone;
1162         ret = 0;
1163     }
1164
1165     return ret;
1166 }