1 /*
2 * $Id: ximdispt.c,v 1.2 2001/06/14 18:16:18 ura Exp $
3 */
4
5 /*
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7 * This file is part of FreeWnn.
8 *
9 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10 *
11 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Emacs; see the file COPYING. If not, write to the
25 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * Commentary:
28 *
29 * Change log:
30 *
31 * Last modified date: 8,Feb.1999
32 *
33 * Code:
34 *
35 */
36
37 /*
38 * Author Name : Li Yuhong
39 * File Name : XimDispt.c
40 * Module Description : This module is to be corresponding to all
41 * protocol requests of X11R6 IM Version 1.0.
42 * Modification History:
43 * Jul 1, 1994 : initial version.
44 */
45 #ifndef X11R5
46 #include <stdio.h>
47 #include <X11/Xlib.h>
48 #ifndef NEED_EVENTS
49 #define NEED_EVENTS
50 #include <X11/Xproto.h> /* for xEvent */
51 #undef NEED_EVENTS
52 #endif /* !NEED_EVENTS */
53 #include "XIMproto.h" /* for ximICValuesReq... */
54 #include "Ximprot.h"
55 #include "sdefine.h"
56 #include "xim.h"
57 #include "sheader.h"
58 #include "ext.h"
59
60 /*--------------------------------------------------------------------*
61 * *
62 * Definition of Constant *
63 * *
64 *--------------------------------------------------------------------*/
65
66 /*
67 * name of "@im" modifier, which is compatible with R5. The reasonable name
68 * might be "xwnmo".
69 */
70 #define XIM_SERVER_NAME "_XWNMO"
71
72 #define BASE_IM_ID 0 /* valid XIMID > 0 */
73 #define BUFFER_MAX 128
74
75 #define ICPreeditAttributes 28 /* ic attr id. */
76 #define ICStatusAttributes 29
77 #define ICSeparatorOfNestedList 30
78
79 #define XIM_EXT_SET_EVENT_MASK 128 /* extension must be >= 128 */
80 #if defined(EXT_MOVE) || defined(SPOT) /* SPOT is name in Xsi R5 */
81 #define XIM_EXT_MOVE 130
82 #endif /* defined(EXT_MOVE) || defined(SPOT) */
83
84 #define NO_NEST (XIMAttrList)NULL
85 #define END_OF_XIMATTRLIST {0, 0, (char *)NULL, ((XIMAttrList)NULL)}
86
87 #define XIMNoString (1L)
88 #define XIMNoFeedback (2L)
89
90
91 /*--------------------------------------------------------------------*
92 * *
93 * Definition of Local Data Type *
94 * *
95 *--------------------------------------------------------------------*/
96
97 #define PIXMAP CARD32 /* for CALLBACKS only */
98
99 /*
100 * XIM attribute structure for both IM and IC value.
101 */
102 typedef struct _XIMAttrRec
103 {
104 CARD16 attr_id; /* attr id */
105 CARD16 type; /* type of attr */
106 char *name; /* name of attr */
107 struct _XIMAttrRec *nest; /* nested list */
108 }
109 XIMAttrRec, *XIMAttrList;
110
111 /*
112 * XIM client structure connected to this server.
113 */
114 typedef struct _XIMContextRec
115 {
116 XIMID im_id; /* IM id */
117 struct _XIMContextRec *next; /* next of client */
118 }
119 XIMContextRec, *XIMContextList;
120
121 /*
122 * extension.
123 */
124 typedef struct
125 {
126 char *name; /* ext name */
127 CARD8 major_code; /* ext major opcode */
128 CARD8 minor_code; /* ext minor opcode */
129 }
130 XIMQueryExtRec;
131
132 #ifdef DYNAMIC_EVENT_FLOW_MODEL
133 /*
134 * just example for Dynamic Event Flow Model.
135 */
136 typedef struct
137 {
138 KeySym key;
139 KeySym modifier;
140 unsinged long modifier_mask;
141 }
142 TriggerKeysRec, *TriggerKeysList;
143
144 static TriggerKeyRec trigger_keys_list[] = {
145 {XK_backslash, XK_Control_L, ControlMask}
146 }
147 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
148
149
150 /*--------------------------------------------------------------------*
151 * *
152 * Definition of Macro *
153 * *
154 *--------------------------------------------------------------------*/
155
156 /*
157 * assign a unique id.
158 */
159 #define ALLOC_ID(n) (++n)
160
161 /*
162 * shared CT string buffer.
163 */
164 #define GET_SHARED_CT_BUFFER() (ct_buf)
165
166 /*
167 * swap data of protocol.
168 */
169 #define GET_CARD16(s) \
170 ((CARD16)((need_byteswap() == True)? byteswap_s(s): s))
171 #define GET_CARD32(s) \
172 ((CARD32)((need_byteswap() == True)? byteswap_l(s): s))
173
174 /*
175 * Pad(n) for protocol data on 4-byte word boundory.
176 */
177 #define PAD(n) ((4 - (n) % 4) % 4)
178
179 /*
180 * pre-make memory for frequent allocation of Request/Reply protocol data.
181 */
182 #define MALLOC_REQUEST(n) \
183 (((n) > (sizeof buffer_request))? (CARD8 *)Malloc(n): &buffer_request[0])
184 #define MALLOC_REPLY(n) \
185 (((n) > (sizeof buffer_reply))? (CARD8 *)Malloc(n): &buffer_reply[0])
186 #define FREE(p) \
187 {if ((p) != &buffer_request[0] && (p) != &buffer_reply[0]) XFree(p);}
188
189 #define XIM_SERIALNUMBER(serial) \
190 (CARD16)(((unsigned long)serial >> 16) & 0xffff)
191 #define XIM_SET_SERIALNUMBER(serial) \
192 (((unsigned long)serial & 0xffff) << 16)
193
194 #define LENGTH_KEYSYM(f, k) \
195 (((f)&XimLookupKeySym)? (sizeof(CARD16)+k): 0)
196 #define LENGTH_STRING_WITH_FLAG(f, n) \
197 (((f)&XimLookupChars)? (sizeof(CARD16)+n+PAD(n)): 0)
198
199 #define LENGTH_STRING(n) ((n > 0) ? \
200 (sizeof(CARD16) + /* 2 n string length */ \
201 n + /* n string */ \
202 PAD(sizeof(CARD16) + n)): 0) /* p Pad(2 + n) */
203 #define LENGTH_FEEDBACK(n) ((n > 0)? \
204 (sizeof(CARD16) + /* 2 m byte length */ \
205 sizeof(CARD16) + /* 2 unused */ \
206 sizeof(CARD32) * n): 0) /* m LISTofXIMFEEDBACK */
207
208 #define CUR_IM_ID() (cur_x->im_id)
209 #define CUR_IC_ID() (cur_x->number)
210 #define CUR_CLIENT_EVENT() ((XEvent *)&(cur_x->cur_event))
211
212 #define LENGTH_TEXT(t, sl, fn) ((t == XIMTextType)? \
213 (LENGTH_STRING(sl) + LENGTH_FEEDBACK(fn)): 0)
214 #define LENGTH_PIXMAP(t) ((t != XIMTextType)? sizeof(PIXMAP): 0)
215
216
217 /*--------------------------------------------------------------------*
218 * *
219 * Definition of Local Variable *
220 * *
221 *--------------------------------------------------------------------*/
222
223 static CARD8 buffer_request[BUFSIZ]; /* for protocol request */
224 static CARD8 buffer_reply[BUFSIZ]; /* for protocol reply */
225
226 /*
227 * X selection atom, target and property in pre-connection.
228 */
229 static Atom transport_target;
230 /* atom name of TRANSPORT target */
231 static Atom locale_target; /* atom name of LOCALE target */
232 static unsigned char *transport_prop;
233 /* string prop of TRANSPORT target */
234 static unsigned char *locale_prop; /* string prop of LOCALE target */
235
236 /*
237 * comma-separated list of locales supported by this server.
238 */
239 static unsigned char *locale_supported;
240
241 static XIMContextList ximlist; /* list of comming IM client */
242 static int cur_status; /* current protol status */
243 static XIMID cur_im_id; /* current client IM id */
244 static XICID cur_ic_id; /* current client IC id */
245 static char cur_use_lang[BUFFER_MAX];
246 /* current lang from XIM_OPEN */
247
248 /*
249 * list of IM attributes.
250 */
251 static XIMAttrRec im_attr[] = {
252 {ICInputStyle, XimType_XIMStyles, XNQueryInputStyle, NO_NEST},
253 END_OF_XIMATTRLIST
254 };
255
256 /*
257 * list of IC preedit attributes.
258 */
259 static XIMAttrRec ic_attr_pre_area[] = {
260 {ICArea, XimType_XRectangle, XNArea, NO_NEST},
261 {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
262 {ICSpotLocation, XimType_XPoint, XNSpotLocation, NO_NEST},
263 {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
264 {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
265 {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
266 {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
267 {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
268 {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
269 {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
270 {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
271 {ICSeparatorOfNestedList,
272 XimType_SeparatorOfNestedList,
273 XNSeparatorofNestedList, NO_NEST},
274 END_OF_XIMATTRLIST
275 };
276
277 /*
278 * list of IC status attributes.
279 */
280 static XIMAttrRec ic_attr_sts_area[] = {
281 {ICArea, XimType_XRectangle, XNArea, NO_NEST},
282 {ICAreaNeeded, XimType_XRectangle, XNAreaNeeded, NO_NEST},
283 {ICColormap, XimType_CARD32, XNColormap, NO_NEST},
284 {ICStdColormap, XimType_CARD32, XNStdColormap, NO_NEST},
285 {ICForeground, XimType_CARD32, XNForeground, NO_NEST},
286 {ICBackground, XimType_CARD32, XNBackground, NO_NEST},
287 {ICBackgroundPixmap, XimType_CARD32, XNBackgroundPixmap, NO_NEST},
288 {ICFontSet, XimType_XFontSet, XNFontSet, NO_NEST},
289 {ICLineSpace, XimType_CARD32, XNLineSpace, NO_NEST},
290 {ICCursor, XimType_CARD32, XNCursor, NO_NEST},
291 {ICSeparatorOfNestedList,
292 XimType_SeparatorOfNestedList,
293 XNSeparatorofNestedList, NO_NEST},
294 END_OF_XIMATTRLIST
295 };
296
297 /*
298 * list of IC attributes.
299 */
300 static XIMAttrRec ic_attr[] = {
301 {ICInputStyle, XimType_CARD32, XNInputStyle, NO_NEST},
302 {ICClientWindow, XimType_Window, XNClientWindow, NO_NEST},
303 {ICFocusWindow, XimType_Window, XNFocusWindow, NO_NEST},
304 {ICFilterEvents, XimType_CARD32, XNFilterEvents, NO_NEST},
305 {ICPreeditAttributes, XimType_NEST, XNPreeditAttributes, ic_attr_pre_area},
306 {ICStatusAttributes, XimType_NEST, XNStatusAttributes, ic_attr_sts_area},
307 END_OF_XIMATTRLIST
308 };
309
310 /*
311 * list of extension supported.
312 */
313 static XIMQueryExtRec extension_list[] = {
314 {"XIM_EXT_SET_EVENT_MASK", XIM_EXT_SET_EVENT_MASK, 0},
315 #if defined(EXT_MOVE) || defined(SPOT)
316 {"XIM_EXT_MOVE", XIM_EXT_MOVE, 0}
317 #endif /* defined(EXT_MOVE) || defined(SPOT) */
318 };
319
320 static CARD8 imattr_list[BUFSIZ]; /* packed im_attr list */
321 static CARD8 icattr_list[BUFSIZ]; /* packed ic_attr list */
322 static INT16 imattr_list_size; /* byte length */
323 static INT16 icattr_list_size; /* byte length */
324
325
326 /*--------------------------------------------------------------------*
327 * *
328 * Declaration of Extenal Variable and Function *
329 * *
330 *--------------------------------------------------------------------*/
331
332 extern XIMCmblk *cur_cblk; /* current client block */
333
334 extern int XmuGetHostname (); /* in SysUtil.h of Xmu */
335
336 /*--------------------------------------------------------------------*
337 * *
338 * Definition of Public Variable and Function *
339 * *
340 *--------------------------------------------------------------------*/
341
342 Atom server_id; /* atom name of this server "@im" */
343
344 int xim_send_nofilter (); /* used before its definition. */
345
346 /*--------------------------------------------------------------------*
347 * *
348 * Private Functions *
349 * *
350 *--------------------------------------------------------------------*/
351
352 /*
353 * Function Name : _WriteToClientFlush()
354 * Description : write data to client immediately with flush action.
355 * same as do_socket.c: _WriteToClient() if no flush.
356 * Parameter :
357 * p : pointer to data.
358 * num : byte length of data.
359 * Returned Value:
360 * >= 0 : byte length of data written to client.
361 * < 0 : error in writing.
362 */
363 static int
_WriteToClientFlush(p,num)364 _WriteToClientFlush (p, num)
365 char *p;
366 int num;
367 {
368 int ret;
369
370 if ((ret = _WriteToClient (p, num)) >= 0)
371 {
372 if (_Send_Flush () == 0)
373 return ret; /* success */
374 }
375 return ret;
376 }
377
378 /*
379 * Function Name : _XimWireToEvent()
380 * Description : convert xEvent to XEvent, modified from Xlibint.c:
381 * _XWireToEvent().
382 * Parameter :
383 * dpy : pointer to X display.
384 * serial : serial number of event.
385 * event : pointer to data of X protocol xEvent
386 * re : pointer to data of XEvent, returned.
387 * Returned Value:
388 * True : conversion is successful.
389 * False : error.
390 */
391 static Bool
_XimWireToEvent(dpy,serial,event,re)392 _XimWireToEvent (dpy, serial, event, re)
393 register Display *dpy; /* pointer to display structure */
394 register int serial; /* serial number of event */
395 register xEvent *event; /* wire protocol event */
396 register XEvent *re; /* pointer to where event should be reformatted */
397 {
398
399 re->type = event->u.u.type & 0x7f;
400 ((XAnyEvent *) re)->serial = XIM_SET_SERIALNUMBER (serial);
401 ((XAnyEvent *) re)->send_event = ((event->u.u.type & 0x80) != 0);
402 ((XAnyEvent *) re)->display = dpy;
403
404 /* Ignore the leading bit of the event type since it is set when a
405 client sends an event rather than the server. */
406
407 switch (event->u.u.type & 0177)
408 {
409 case KeyPress:
410 case KeyRelease:
411 {
412 register XKeyEvent *ev = (XKeyEvent *) re;
413 ev->root = event->u.keyButtonPointer.root;
414 ev->window = event->u.keyButtonPointer.event;
415 ev->subwindow = event->u.keyButtonPointer.child;
416 ev->time = event->u.keyButtonPointer.time;
417 ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
418 ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
419 ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
420 ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
421 ev->state = event->u.keyButtonPointer.state;
422 ev->same_screen = event->u.keyButtonPointer.sameScreen;
423 ev->keycode = event->u.u.detail;
424 }
425 break;
426 case ButtonPress:
427 case ButtonRelease:
428 {
429 register XButtonEvent *ev = (XButtonEvent *) re;
430 ev->root = event->u.keyButtonPointer.root;
431 ev->window = event->u.keyButtonPointer.event;
432 ev->subwindow = event->u.keyButtonPointer.child;
433 ev->time = event->u.keyButtonPointer.time;
434 ev->x = cvtINT16toInt (event->u.keyButtonPointer.eventX);
435 ev->y = cvtINT16toInt (event->u.keyButtonPointer.eventY);
436 ev->x_root = cvtINT16toInt (event->u.keyButtonPointer.rootX);
437 ev->y_root = cvtINT16toInt (event->u.keyButtonPointer.rootY);
438 ev->state = event->u.keyButtonPointer.state;
439 ev->same_screen = event->u.keyButtonPointer.sameScreen;
440 ev->button = event->u.u.detail;
441 }
442 break;
443 default:
444 return False;
445 }
446 return True;
447 }
448
449 /*
450 * Function Name : _XimEventToWire()
451 * Description : convert XEvent to xEvent, modified from EvToWire.c:
452 * _XEventToWire().
453 * Parameter :
454 * re : pointer to data of XEvent.
455 * event : pointer to data of X protocol xEvent, returned
456 * Returned Value:
457 * True : conversion is successful.
458 * False : error.
459 */
460 static Bool
_XimEventToWire(re,event)461 _XimEventToWire (re, event)
462 register XEvent *re; /* pointer to where event should be reformatted */
463 register xEvent *event; /* wire protocol event */
464 {
465 switch (event->u.u.type = re->type)
466 {
467 case KeyPress:
468 case KeyRelease:
469 {
470 register XKeyEvent *ev = (XKeyEvent *) re;
471 event->u.keyButtonPointer.root = ev->root;
472 event->u.keyButtonPointer.event = ev->window;
473 event->u.keyButtonPointer.child = ev->subwindow;
474 event->u.keyButtonPointer.time = ev->time;
475 event->u.keyButtonPointer.eventX = ev->x;
476 event->u.keyButtonPointer.eventY = ev->y;
477 event->u.keyButtonPointer.rootX = ev->x_root;
478 event->u.keyButtonPointer.rootY = ev->y_root;
479 event->u.keyButtonPointer.state = ev->state;
480 event->u.keyButtonPointer.sameScreen = ev->same_screen;
481 event->u.u.detail = ev->keycode;
482 }
483 break;
484 case ButtonPress:
485 case ButtonRelease:
486 {
487 register XButtonEvent *ev = (XButtonEvent *) re;
488 event->u.keyButtonPointer.root = ev->root;
489 event->u.keyButtonPointer.event = ev->window;
490 event->u.keyButtonPointer.child = ev->subwindow;
491 event->u.keyButtonPointer.time = ev->time;
492 event->u.keyButtonPointer.eventX = ev->x;
493 event->u.keyButtonPointer.eventY = ev->y;
494 event->u.keyButtonPointer.rootX = ev->x_root;
495 event->u.keyButtonPointer.rootY = ev->y_root;
496 event->u.keyButtonPointer.state = ev->state;
497 event->u.keyButtonPointer.sameScreen = ev->same_screen;
498 event->u.u.detail = ev->button;
499 }
500 break;
501 default:
502 return False;
503 }
504 return True;
505 }
506
507 /*
508 * get list of locale names as the format:
509 * "locale_1,locale_2,...,locale_n"
510 * and return the length of the string above.
511 */
512 static char *
GetLocaleSupported()513 GetLocaleSupported ()
514 {
515 return (!xim->supported_language) ? "C" : xim->supported_language;
516 }
517
518 /*
519 * Function Name : _CheckLocaleName()
520 * Description : check if the client locale is supported in this server.
521 * Parameter :
522 * buf : string buffer of client locale.
523 * loc_name : comma-separated list of locales supported in this server.
524 * Returned Value:
525 * True : it is supported.
526 * False : not supproted.
527 */
528 static Bool
_CheckLocaleName(buf,loc_name)529 _CheckLocaleName (buf, loc_name)
530 CARD8 *buf;
531 char *loc_name;
532 {
533 int str_len = (int) buf[0];
534 int len;
535 char *ptr = (char *) locale_supported;
536 char *str = (char *) &buf[1];
537 register char *p;
538
539 loc_name[0] = '\0';
540 for (;;)
541 {
542 for (p = ptr; ((*p != ',') && (*p)); p++);
543 len = (int) (p - ptr);
544 if ((str_len == len) && (!strncmp (str, ptr, len)))
545 {
546 (void) strncpy (loc_name, str, len);
547 loc_name[len] = '\0';
548 return True;
549 }
550 if (!(*p))
551 break;
552 ptr = p + 1;
553 }
554 return False;
555 }
556
557 /*
558 * Function Name : GetIMWithId()
559 * Description : search a client context with IM id.
560 * Parameter :
561 * im_id : client input-method-id.
562 * Returned Value:
563 * XIMContextRec *
564 * : pointer to the client context found.
565 * NULL : not found.
566 */
567 static XIMContextRec *
GetIMWithId(im_id)568 GetIMWithId (im_id)
569 register XIMID im_id;
570 {
571 register XIMContextRec *im;
572
573 for (im = ximlist; im; im = im->next)
574 {
575 if (im->im_id == im_id)
576 return im;
577 }
578 return (XIMContextRec *) NULL;
579 }
580
581 /*
582 * Function Name : RemoveIMWithId()
583 * Description : remove a IM client context.
584 * Parameter :
585 * im_id : client input-method-id.
586 * Returned Value:
587 * True : the IM client context with im_id is removed from list
588 * and is freed its memory.
589 * False : not found with this im_id.
590 */
591 static Bool
RemoveIMWithId(im_id)592 RemoveIMWithId (im_id)
593 XIMID im_id;
594 {
595 register XIMContextRec *im, *pre_im;
596
597 for (im = pre_im = ximlist; im; pre_im = im, im = im->next)
598 {
599 if (im->im_id == im_id)
600 {
601 if (pre_im != im)
602 {
603 pre_im->next = im->next;
604 }
605 else
606 {
607 ximlist = im->next;
608 }
609 break;
610 }
611 }
612 if (!im)
613 return False;
614 XFree ((char *) im);
615 return True;
616 }
617
618 /*
619 * Function Name : GetICWithId()
620 * Description : search a client structure with IC id.
621 * Parameter :
622 * ic_id : client input-context-id.
623 * Returned Value:
624 * XIMClientRec*
625 * : pointer to the client structure found.
626 * NULL : not found.
627 */
628 static XIMClientRec *
GetICWithId(ic_id)629 GetICWithId (ic_id)
630 register int ic_id;
631 {
632 register XIMClientRec *xc;
633
634 for (xc = ximclient_list; xc != NULL; xc = xc->next)
635 {
636 if (xc->number == ic_id)
637 return xc;
638 }
639 return (XIMClientRec *) NULL;
640 }
641
642 /*
643 * Function Name : AddHead()
644 * Description : fill head data to a protocol reply which will be
645 * sent to client. The head data to be filed is as follows:
646 * CARD8 major_opcode
647 * CARD8 minor_opcode
648 * CARD16 data length in 4-byte word
649 * Parameter :
650 * reply : pointer to a protocol reply structure, which is
651 * to be filled head data.
652 * major_code : major opcode of this protocol.
653 * minor_code : minor opcode of this protocol.
654 * len : data length of protocol except head.
655 * Returned Value:
656 * > 0 : byte length of head data, always XIM_HEADER_SIZE.
657 */
658 static int
AddHead(reply,major_code,minor_code,len)659 AddHead (reply, major_code, minor_code, len)
660 CARD8 *reply;
661 CARD8 major_code;
662 CARD8 minor_code;
663 int len;
664 {
665 CARD8 *buf_8 = reply;
666 CARD16 *buf_16 = (CARD16 *) (reply + sizeof (CARD8) * 2);
667
668 buf_8[0] = major_code;
669 buf_8[1] = minor_code;
670 buf_16[0] = GET_CARD16 (len / 4);
671 return XIM_HEADER_SIZE;
672 }
673
674 /*
675 * Function Name : SetClientSync()
676 * Description : set the client to a sync flag.
677 * Parameter :
678 * xc : pointer to a client structure.
679 * sync : flag of sync.
680 * Returned Value:
681 * <none>
682 */
683 #ifdef NEED_FUNCTION
684
685 static void
SetClientSync(xc,sync)686 SetClientSync (xc, sync)
687 XIMClientRec *xc;
688 Bool sync;
689 {
690 xc->sync_needed = sync;
691 }
692
693 static Bool
AllSyncDone(im_id,ic_id)694 AllSyncDone (im_id, ic_id)
695 XIMID im_id;
696 XICID im_cd;
697 {
698 return True;
699 }
700
701 static void
SyncAll(im_id,ic_id)702 SyncAll (im_id, ic_id)
703 XIMID im_id;
704 XICID im_cd;
705 {
706 }
707
708 #else
709
710 #define SetClientSync(xc, sync) ((xc)->sync_needed = sync)
711 #define AllSyncDone(im_id, ic_id) (True)
712 #define SyncAll(im_id, ic_id)
713
714 #endif /* NEED_FUNCTION */
715
716 /*
717 * Function Name : ClientSyncDone()
718 * Description : If this client has True flag needed to do sync, do it
719 * and turn off the sync flag (False).
720 * Parameter :
721 * xc : pointer to a client structure.
722 * Returned Value:
723 * True : yes, sync has done.
724 * False : no sync.
725 */
726 static Bool
ClientSyncDone(xc)727 ClientSyncDone (xc)
728 XIMClientRec *xc;
729 {
730 Bool sync_done;
731
732 sync_done = xc->sync_needed;
733 xc->sync_needed = False;
734 return sync_done;
735 }
736
737 /*
738 * Function Name : GetAuth()
739 * Description : get names of authentification from IM library.
740 * Parameter :
741 * list : buffer list.
742 * num : number of list elements.
743 * length : byte length of buffer list.
744 * names_returned
745 * : auth name returned.
746 * Returned Value:
747 * True : successed.
748 * False : wrong auth name.
749 */
750
751 /*ARGSUSED*/ static Bool
GetAuth(list,num,length,names_return)752 GetAuth (list, num, length, names_return)
753 CARD8 *list;
754 int num;
755 int length;
756 char *names_return;
757 {
758 /* it is free authentification so far. */
759 return True;
760 }
761
762 /*
763 * Function Name : CreateAttrList()
764 * Description : pack IM/IC attribute list to a compact data.
765 * Parameter :
766 * table : list of IM/IC attributes, end with the empty name.
767 * list : returned data that contains packed list of attribute.
768 * Returned Value:
769 * >= 0 : byte length of packed list.
770 */
771 static int
CreateAttrList(table,list)772 CreateAttrList (table, list)
773 XIMAttrList table;
774 CARD8 *list;
775 {
776 CARD16 *buf_16;
777 INT16 total = 0;
778 int len, i;
779
780 for (i = 0; table[i].name; i++)
781 {
782 buf_16 = (CARD16 *) list;
783 len = strlen (table[i].name);
784 buf_16[0] = GET_CARD16 (table[i].attr_id); /* 2 attr ID */
785 buf_16[1] = GET_CARD16 (table[i].type); /* 2 type */
786 buf_16[2] = GET_CARD16 (len); /* 2 length */
787 memcpy ((char *) &buf_16[3], table[i].name, len); /* n attr */
788 len = sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16) + len + PAD (len + 2);
789 list += len;
790 total += len;
791 if (table[i].nest)
792 {
793 len = CreateAttrList (table[i].nest, list);
794 list += len;
795 total += len;
796 }
797 }
798 return total;
799 }
800
801 /*
802 * Function Name : InitiateProtocol()
803 * Description : do some initial works.
804 * Parameter :
805 * <none>
806 * Returned Value:
807 * <none>
808 */
809 static void
InitiateProtocol()810 InitiateProtocol ()
811 {
812 ximlist = (XIMContextList) NULL;
813
814 imattr_list_size = CreateAttrList (im_attr, imattr_list);
815 icattr_list_size = CreateAttrList (ic_attr, icattr_list);
816 }
817
818 /*
819 * Function Name : CheckInputStyle()
820 * Description : check if the passed input style is supported.
821 * Parameter :
822 * input_style : the input style to be checked.
823 * Returned Value:
824 * True : supported.
825 * False : not supported.
826 */
827 static Bool
CheckInputStyle(input_style)828 CheckInputStyle (input_style)
829 INT32 input_style;
830 {
831 int i;
832
833 for (i = 0; i < MAX_SUPPORT_STYLE; i++)
834 {
835 if (xim->supported_style[i] == input_style)
836 {
837 return True;
838 }
839 }
840 return False;
841 }
842
843 /*
844 * Function Name : ConvErrorCode()
845 * Description : convert error code used in Xsi R5 IM to R6 IM.
846 * Parameter :
847 * x11r5_code : error code of Xsi R5 IM.
848 * Returned Value:
849 * > 0 : errro code of R6 IM
850 */
851 static int
ConvErrorCode(x11r5_code)852 ConvErrorCode (x11r5_code)
853 short x11r5_code;
854 {
855 switch (x11r5_code)
856 {
857 case AllocError:
858 return XIM_BadAlloc;
859 case BadStyle:
860 return XIM_BadStyle;
861 case BadClientWindow:
862 return XIM_BadClientWindow;
863 case BadFocusWindow:
864 return XIM_BadFocusWindow;
865 case BadLanguage:
866 return XIM_LocaleNotSupported;
867 case BadSpotLocation:
868 return XIM_BadSpotLocation;
869 case BadFontSet:
870 return XIM_BadName; /* or XIM_BadStyle */
871 default:
872 return XIM_BadSomething;
873 }
874 }
875
876 /*
877 * Function Name : ConvAreaAttr()
878 * Description : convert byte data to IC attribute of Area.
879 * Parameter :
880 * value : the byte data.
881 * size : byte length of the data.
882 * ic_attr_req : contain Area attribute to be filled.
883 * Returned Value:
884 * = 0 : successed.
885 * > 0 : error, the number is error code.
886 */
887 static int
ConvAreaAttr(value,size,ic_attr_req)888 ConvAreaAttr (value, size, ic_attr_req)
889 CARD8 *value;
890 int size;
891 ximICAttributesReq *ic_attr_req;
892 {
893 CARD16 *buf_16 = (CARD16 *) value;
894
895 if (size != (sizeof (CARD16) << 2))
896 return XIM_BadAlloc;
897
898 ic_attr_req->area_x = (INT16) GET_CARD16 (buf_16[0]);
899 ic_attr_req->area_y = (INT16) GET_CARD16 (buf_16[1]);
900 ic_attr_req->area_width = GET_CARD16 (buf_16[2]);
901 ic_attr_req->area_height = GET_CARD16 (buf_16[3]);
902 return 0;
903 }
904
905 /*
906 * Function Name : ConvAreaNeededAttr()
907 * Description : convert byte data to IC attribute of AreaNeeded.
908 * Parameter :
909 * value : the byte data.
910 * size : byte length of the data.
911 * ic_attr_req : contain AreaNeeded attribute to be filled.
912 * Returned Value:
913 * = 0 : successed.
914 * > 0 : error, the number is error code.
915 */
916 static int
ConvAreaNeededAttr(value,size,ic_attr_req)917 ConvAreaNeededAttr (value, size, ic_attr_req)
918 CARD8 *value;
919 int size;
920 ximICAttributesReq *ic_attr_req;
921 {
922 CARD16 *buf_16 = (CARD16 *) value;
923
924 if (size != (sizeof (CARD16) << 2))
925 return XIM_BadAlloc;
926
927 ic_attr_req->areaneeded_width = GET_CARD16 (buf_16[2]);
928 ic_attr_req->areaneeded_height = GET_CARD16 (buf_16[3]);
929 return 0;
930 }
931
932 /*
933 * Function Name : ConvSpotAttr()
934 * Description : convert byte data to IC attribute of Spot.
935 * Parameter :
936 * value : the byte data.
937 * size : byte length of the data.
938 * ic_attr_req : contain Spot attribute to be filled.
939 * Returned Value:
940 * = 0 : successed.
941 * > 0 : error, the number is error code.
942 */
943 static int
ConvSpotAttr(value,size,ic_attr_req)944 ConvSpotAttr (value, size, ic_attr_req)
945 CARD8 *value;
946 int size;
947 ximICAttributesReq *ic_attr_req;
948 {
949 CARD16 *buf_16 = (CARD16 *) value;
950
951 if (size != (sizeof (CARD16) + sizeof (CARD16)))
952 return XIM_BadAlloc;
953
954 ic_attr_req->spot_x = (INT16) GET_CARD16 (buf_16[0]);
955 ic_attr_req->spot_y = (INT16) GET_CARD16 (buf_16[1]);
956 return 0;
957 }
958
959 /*
960 * Function Name : ConvFontSetAttr()
961 * Description : convert byte data to IC attribute of FontSet name.
962 * Parameter :
963 * value : the byte data.
964 * size : byte length of the data.
965 * ic_attr_req : contain FontSet attribute to be filled.
966 * Returned Value:
967 * = 0 : successed.
968 * > 0 : error, the number is error code.
969 */
970 static int
ConvFontSetAttr(value,size,base_font_name)971 ConvFontSetAttr (value, size, base_font_name)
972 CARD8 *value;
973 int size;
974 char **base_font_name;
975 {
976 CARD16 *buf_16 = (CARD16 *) value;
977 char *fname;
978 int len;
979
980 len = (int) GET_CARD16 (buf_16[0]);
981 if (len > size)
982 return XIM_BadAlloc;
983 if (!(fname = Malloc (len + 1)))
984 return XIM_BadAlloc;
985 (void) strncpy (fname, (char *) &buf_16[1], len);
986 fname[len] = '\0';
987 *base_font_name = fname;
988 return 0;
989 }
990
991 /*
992 * Function Name : DecodeICNestedAttributes()
993 * Description : decode IC nested attributes
994 * Parameter :
995 * list : list of IC attribute, packed data.
996 * size : byte length of list.
997 * ic_attr_req : IC attribute structure to be filled.
998 * font : base font name to be returned. The caller should
999 * free it after use.
1000 * Returned Value:
1001 * = 0 : successed.
1002 * > 0 : error, the number is error code.
1003 */
1004 static int
DecodeICNestedAttributes(list,size,mask,ic_attr_req,font)1005 DecodeICNestedAttributes (list, size, mask, ic_attr_req, font)
1006 CARD8 *list;
1007 int size;
1008 CARD32 *mask;
1009 ximICAttributesReq *ic_attr_req;
1010 char **font;
1011 {
1012 CARD16 *buf_16;
1013 CARD32 *buf_32;
1014 CARD32 mask_base, mask_ret;
1015 int ret, have_more;
1016 int len, tmpl, attr_id;
1017
1018 ret = 0;
1019 mask_base = *mask;
1020 mask_ret = 0;
1021 have_more = 1;
1022 while (size > 0 && have_more)
1023 {
1024 buf_16 = (CARD16 *) list;
1025 attr_id = (int) GET_CARD16 (buf_16[0]); /* 2 attribute id */
1026 len = (int) GET_CARD16 (buf_16[1]); /* n length of value */
1027 tmpl = sizeof (CARD16) + sizeof (CARD16);
1028 list += tmpl;
1029 size -= tmpl;
1030 buf_16 = (CARD16 *) list;
1031 buf_32 = (CARD32 *) list;
1032 switch (attr_id)
1033 {
1034 case ICArea:
1035 mask_ret |= (1 << (ICArea + mask_base));
1036 ret = ConvAreaAttr (list, len, ic_attr_req);
1037 break;
1038 case ICAreaNeeded:
1039 mask_ret |= (1 << (ICAreaNeeded + mask_base));
1040 ret = ConvAreaNeededAttr (list, len, ic_attr_req);
1041 break;
1042 case ICSpotLocation:
1043 mask_ret |= (1 << (ICSpotLocation + mask_base));
1044 ret = ConvSpotAttr (list, len, ic_attr_req);
1045 break;
1046 case ICColormap:
1047 mask_ret |= (1 << (ICColormap + mask_base));
1048 ic_attr_req->colormap = (Colormap) GET_CARD32 (buf_32[0]);
1049 break;
1050 case ICStdColormap:
1051 mask_ret |= (1 << (ICStdColormap + mask_base));
1052 ic_attr_req->std_colormap = (Atom) GET_CARD32 (buf_32[0]);
1053 break;
1054 case ICForeground:
1055 mask_ret |= (1 << (ICForeground + mask_base));
1056 ic_attr_req->foreground = GET_CARD32 (buf_32[0]);
1057 break;
1058 case ICBackground:
1059 mask_ret |= (1 << (ICBackground + mask_base));
1060 ic_attr_req->background = GET_CARD32 (buf_32[0]);
1061 break;
1062 case ICBackgroundPixmap:
1063 mask_ret |= (1 << (ICBackgroundPixmap + mask_base));
1064 ic_attr_req->pixmap = (Pixmap) GET_CARD32 (buf_32[0]);
1065 break;
1066 case ICFontSet:
1067 mask_ret |= (1 << (ICFontSet + mask_base));
1068 ret = ConvFontSetAttr (list, len, font);
1069 break;
1070 case ICLineSpace:
1071 mask_ret |= (1 << (ICLineSpace + mask_base));
1072 ic_attr_req->line_space = (INT16) GET_CARD32 (buf_32[0]);
1073 break;
1074 case ICCursor:
1075 mask_ret |= (1 << (ICCursor + mask_base));
1076 ic_attr_req->cursor = (Cursor) GET_CARD32 (buf_32[0]);
1077 break;
1078 case ICSeparatorOfNestedList:
1079 have_more = 0;
1080 break;
1081 default:
1082 have_more = 0;
1083 continue;
1084 }
1085 if (ret)
1086 return ret;
1087 len = len + /* n value */
1088 PAD (len); /* p Pad(n) */
1089 list += len;
1090 size -= len;
1091 }
1092 *mask = mask_ret;
1093 return 0;
1094 }
1095
1096 /*
1097 * Function Name : DecodeICAttributes()
1098 * Description : parse all IC attributes
1099 * Parameter :
1100 * list : list of IC attributes, packed data.
1101 * size : byte length of list.
1102 * ic_attr_req : IC attribute structure to be filled.
1103 * pre_req : preedit attributes to be filled.
1104 * st_req : status attributes to be filled.
1105 * pre_font : preedit base font name to be returned. The caller should
1106 * free it after use.
1107 * st_font : status base font name to be returned. The caller should
1108 * free it after use.
1109 * Returned Value:
1110 * = 0 : successed.
1111 * > 0 : error, the number is error code.
1112 */
1113 static int
DecodeICAttributes(list,size,ic_req,pre_req,st_req,pre_font,st_font)1114 DecodeICAttributes (list, size, ic_req, pre_req, st_req, pre_font, st_font)
1115 CARD8 *list;
1116 int size;
1117 ximICValuesReq *ic_req;
1118 ximICAttributesReq *pre_req;
1119 ximICAttributesReq *st_req;
1120 char **pre_font;
1121 char **st_font;
1122 {
1123 CARD16 *buf_16;
1124 CARD32 *buf_32;
1125 CARD32 mask;
1126 int ret, len, attr_id;
1127 int tmpl;
1128
1129 ret = 0;
1130 ic_req->mask = (CARD32) 0;
1131 while (size > 0)
1132 {
1133 buf_16 = (CARD16 *) list;
1134 attr_id = (int) GET_CARD16 (buf_16[0]);
1135 len = (int) GET_CARD16 (buf_16[1]);
1136 tmpl = sizeof (CARD16) + /* 2 attribute id */
1137 sizeof (CARD16); /* 2 value length */
1138 list += tmpl;
1139 size -= tmpl;
1140 buf_16 = (CARD16 *) list;
1141 buf_32 = (CARD32 *) list;
1142 switch (attr_id)
1143 {
1144 case ICInputStyle:
1145 ic_req->mask |= (1 << ICInputStyle);
1146 ic_req->input_style = (INT32) GET_CARD32 (buf_32[0]);
1147 break;
1148 case ICClientWindow:
1149 ic_req->mask |= (1 << ICClientWindow);
1150 ic_req->c_window = (Window) GET_CARD32 (buf_32[0]);
1151 break;
1152 case ICFocusWindow:
1153 ic_req->mask |= (1 << ICFocusWindow);
1154 ic_req->focus_window = (Window) GET_CARD32 (buf_32[0]);
1155 break;
1156 case ICFilterEvents:
1157 ic_req->mask |= (1 << ICFilterEvents);
1158 ic_req->filter_events = GET_CARD32 (buf_32[0]);
1159 break;
1160 case ICPreeditAttributes:
1161 mask = 0;
1162 ret = DecodeICNestedAttributes (list, len, &mask, pre_req, pre_font);
1163 ic_req->mask |= mask;
1164 break;
1165 case ICStatusAttributes:
1166 mask = StatusOffset;
1167 ret = DecodeICNestedAttributes (list, len, &mask, st_req, st_font);
1168 ic_req->mask |= mask;
1169 break;
1170 default:
1171 ret = XIM_BadProtocol;
1172 break;
1173 }
1174 if (ret)
1175 return ret;
1176 len = len + /* n value */
1177 PAD (len); /* p Pad(n) */
1178 list += len;
1179 size -= len;
1180 }
1181 return 0;
1182 }
1183
1184 /*
1185 * Function Name : SetClientICValues()
1186 * Description : set IC values to a client structure.
1187 * Parameter :
1188 * list : list of IC attributes, packed data.
1189 * size : byte length of list.
1190 * xc : pointer to client structure.
1191 * Returned Value:
1192 * = 0 : successed.
1193 * > 0 : error, the number is error code.
1194 */
1195 static int
SetClientICValues(list,size,xc)1196 SetClientICValues (list, size, xc)
1197 CARD8 *list;
1198 int size;
1199 XIMClientRec *xc;
1200 {
1201 ximICValuesReq ic_req;
1202 ximICAttributesReq pre_req, st_req;
1203 XIMNestLangRec *p = (XIMNestLangRec *) NULL;
1204 char *pre_font = (char *) NULL;
1205 char *st_font = (char *) NULL;
1206 int cur_is_world = 0;
1207 int ret;
1208 short detail;
1209 extern int change_client ();
1210
1211 /* parse IC attributes */
1212 ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
1213 if (ret)
1214 return ret;
1215
1216 /* refer to util: ChangeIC() */
1217
1218 ret = change_client (xc, &ic_req, &pre_req, &st_req, p, cur_is_world, pre_font, st_font, &detail);
1219 if (pre_font)
1220 XFree (pre_font);
1221 if (st_font)
1222 XFree (st_font);
1223 if (p)
1224 free_langlist (p);
1225 if (ret == -1)
1226 return ConvErrorCode (detail);
1227 return 0;
1228 }
1229
1230 /*
1231 * Function Name : EncodeRectangleAttr()
1232 * Description : encode XRectangle to byte data.
1233 * Parameter :
1234 * rect : pointer to the rectangle structure.
1235 * value : encoded byte data.
1236 * size_return : returned byte length of the data.
1237 * Returned Value:
1238 * = 0 : successed.
1239 * > 0 : error, the number is error code.
1240 */
1241 static int
EncodeRectangleAttr(rect,value,size_return)1242 EncodeRectangleAttr (rect, value, size_return)
1243 XRectangle *rect;
1244 CARD8 *value;
1245 int *size_return;
1246 {
1247 CARD16 *buf_16 = (CARD16 *) value;
1248
1249 buf_16[0] = GET_CARD16 (rect->x);
1250 buf_16[1] = GET_CARD16 (rect->y);
1251 buf_16[2] = GET_CARD16 (rect->width);
1252 buf_16[3] = GET_CARD16 (rect->height);
1253 *size_return = sizeof (CARD16) + /* 2 X */
1254 sizeof (CARD16) + /* 2 Y */
1255 sizeof (CARD16) + /* 2 width */
1256 sizeof (CARD16); /* 2 height */
1257 return 0;
1258 }
1259
1260 /*
1261 * Function Name : EncodePointAttr()
1262 * Description : encode XPoint to byte data.
1263 * Parameter :
1264 * rect : pointer to the XPoint structure.
1265 * value : encoded byte data.
1266 * size_return : returned byte length of the data.
1267 * Returned Value:
1268 * = 0 : successed.
1269 * > 0 : error, the number is error code.
1270 */
1271 static int
EncodePointAttr(xc,value,size_return)1272 EncodePointAttr (xc, value, size_return)
1273 XIMClientRec *xc;
1274 CARD8 *value;
1275 int *size_return;
1276 {
1277 CARD16 *buf_16 = (CARD16 *) value;
1278 short spot_x, spot_y;
1279
1280 spot_x = xc->point.x;
1281 spot_y = xc->point.y + FontAscent (xc->cur_xl);
1282 buf_16[0] = GET_CARD16 (spot_x);
1283 buf_16[1] = GET_CARD16 (spot_y);
1284 *size_return = sizeof (CARD16) + /* 2 X */
1285 sizeof (CARD16); /* 2 Y */
1286 return 0;
1287 }
1288
1289 /*
1290 * Function Name : EncodeFontSetAttr()
1291 * Description : encode name of base font set to byte data.
1292 * Parameter :
1293 * rect : pointer to the name.
1294 * value : encoded byte data.
1295 * size_return : returned byte length of the data.
1296 * Returned Value:
1297 * = 0 : successed.
1298 * > 0 : error, the number is error code.
1299 */
1300 static int
EncodeFontSetAttr(base_font_name,value,size_return)1301 EncodeFontSetAttr (base_font_name, value, size_return)
1302 char *base_font_name;
1303 CARD8 *value;
1304 int *size_return;
1305 {
1306 CARD16 *buf_16 = (CARD16 *) value;
1307 int len;
1308
1309 len = strlen ((char *) base_font_name);
1310 buf_16[0] = GET_CARD16 (len);
1311 (void) strncpy ((char *) &buf_16[1], (char *) base_font_name, len);
1312 *size_return = sizeof (CARD16) + len + PAD (sizeof (CARD16) + len);
1313 return 0;
1314 }
1315
1316 /*
1317 * Function Name : EncodeICNestedAttributes()
1318 * Description : encode IC nested attribute structure to byte data.
1319 * Parameter :
1320 * attr_id_list: list of IC attribute id.
1321 * size : byte lenth of the list.
1322 * xc : pointer to client structure.
1323 * ic_attr : pointer to IC nested attribute structure.
1324 * value : encoded byte data.
1325 * size_return : returned byte length of the data.
1326 * num_return : returned number of IC attributes.
1327 * Returned Value:
1328 * = 0 : successed.
1329 * > 0 : error, the number is error code.
1330 */
1331 static int
EncodeICNestedAttributes(attr_id_list,size,xc,ic_attr,value,size_return,num_return)1332 EncodeICNestedAttributes (attr_id_list, size, xc, ic_attr, value, size_return, num_return)
1333 CARD8 *attr_id_list;
1334 int size;
1335 XIMClientRec *xc;
1336 XIMAttributes *ic_attr;
1337 CARD8 *value;
1338 int *size_return;
1339 int *num_return;
1340 {
1341 CARD8 *data;
1342 CARD16 *buf_16;
1343 CARD32 *buf_32;
1344 int ret, len, total, num, attr_id;
1345 int have_more;
1346
1347 ret = 0;
1348 total = num = 0;
1349 have_more = 1;
1350 while (size > 0 && have_more)
1351 {
1352 buf_16 = (CARD16 *) attr_id_list;
1353 attr_id = (int) GET_CARD16 (buf_16[0]);
1354 data = value + sizeof (CARD16) + sizeof (CARD16);
1355 buf_16 = (CARD16 *) data;
1356 buf_32 = (CARD32 *) data;
1357 switch (attr_id)
1358 {
1359 case ICArea:
1360 ret = EncodeRectangleAttr (&(ic_attr->area), data, &len);
1361 break;
1362 case ICAreaNeeded:
1363 ret = EncodeRectangleAttr (&(ic_attr->area_needed), data, &len);
1364 break;
1365 case ICSpotLocation:
1366 ret = EncodePointAttr (xc, data, &len);
1367 break;
1368 case ICColormap:
1369 len = sizeof (CARD32);
1370 buf_32[0] = GET_CARD32 (ic_attr->colormap);
1371 break;
1372 case ICStdColormap:
1373 len = sizeof (CARD32);
1374 buf_32[0] = GET_CARD32 (ic_attr->std_colormap);
1375 break;
1376 case ICForeground:
1377 len = sizeof (CARD32);
1378 buf_32[0] = GET_CARD32 (ic_attr->fg);
1379 break;
1380 case ICBackground:
1381 len = sizeof (CARD32);
1382 buf_32[0] = GET_CARD32 (ic_attr->bg);
1383 break;
1384 case ICBackgroundPixmap:
1385 len = sizeof (CARD32);
1386 buf_32[0] = GET_CARD32 (ic_attr->bg_pixmap);
1387 break;
1388 case ICFontSet:
1389 ret = EncodeFontSetAttr (ic_attr->fontset, data, &len);
1390 break;
1391 case ICLineSpace:
1392 len = sizeof (CARD32);
1393 buf_32[0] = GET_CARD32 (ic_attr->line_space);
1394 break;
1395 case ICCursor:
1396 len = sizeof (CARD32);
1397 buf_32[0] = GET_CARD32 (ic_attr->cursor);
1398 break;
1399 case ICSeparatorOfNestedList:
1400 len = 0;
1401 have_more = 0;
1402 break;
1403 default:
1404 have_more = 0;
1405 continue;
1406 }
1407 if (ret)
1408 return ret;
1409 buf_16 = (CARD16 *) value;
1410 buf_16[0] = GET_CARD16 (attr_id);
1411 buf_16[1] = GET_CARD16 (len);
1412 len = sizeof (CARD16) + /* 2 attribute-id */
1413 sizeof (CARD16) + /* 2 byte length of value */
1414 len + /* n value */
1415 PAD (len); /* p Pad(n) */
1416 value += len;
1417 total += len;
1418 attr_id_list += sizeof (CARD16);
1419 size -= sizeof (CARD16);
1420 num++;
1421 }
1422 *size_return = total;
1423 *num_return = num;
1424 return 0;
1425 }
1426
1427 /*
1428 * Function Name : EncodeICAttributes()
1429 * Description : encode IC attribute structure to byte data.
1430 * Parameter :
1431 * attr_id_list: list of IC attribute id.
1432 * size : byte lenth of the list.
1433 * xc : pointer to client structure.
1434 * value : encoded byte data.
1435 * size_return : returned byte length of the data.
1436 * Returned Value:
1437 * = 0 : successed.
1438 * > 0 : error, the number is error code.
1439 */
1440 static int
EncodeICAttributes(attr_id_list,size,xc,value,size_return)1441 EncodeICAttributes (attr_id_list, size, xc, value, size_return)
1442 CARD8 *attr_id_list;
1443 int size;
1444 XIMClientRec *xc;
1445 CARD8 *value;
1446 int *size_return;
1447 {
1448 CARD8 *data;
1449 CARD16 *buf_16;
1450 CARD32 *buf_32;
1451 int ret, len, total, attr_id, num;
1452 int nested_size;
1453
1454 ret = 0;
1455 total = 0;
1456 while (size > 0)
1457 {
1458 buf_16 = (CARD16 *) attr_id_list;
1459 attr_id = (int) GET_CARD16 (buf_16[0]);
1460 data = value + sizeof (CARD16) + sizeof (CARD16);
1461 buf_16 = (CARD16 *) data;
1462 buf_32 = (CARD32 *) data;
1463 switch (attr_id)
1464 {
1465 case ICInputStyle:
1466 len = sizeof (CARD32);
1467 buf_32[0] = GET_CARD32 (xc->input_style);
1468 break;
1469 case ICClientWindow:
1470 len = sizeof (CARD32);
1471 buf_32[0] = GET_CARD32 (xc->w);
1472 break;
1473 case ICFocusWindow:
1474 len = sizeof (CARD32);
1475 buf_32[0] = GET_CARD32 (xc->focus_window);
1476 break;
1477 case ICFilterEvents:
1478 len = sizeof (CARD32);
1479 buf_32[0] = GET_CARD32 (xc->filter_events);
1480 break;
1481 case ICPreeditAttributes:
1482 ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->pe), data, &len, &num);
1483 if (!ret)
1484 {
1485 nested_size = sizeof (CARD16) * num;
1486 attr_id_list += nested_size;
1487 size -= nested_size;
1488 }
1489 break;
1490 case ICStatusAttributes:
1491 ret = EncodeICNestedAttributes ((attr_id_list + sizeof (CARD16)), (size - sizeof (CARD16)), xc, &(xc->st), data, &len, &num);
1492 if (!ret)
1493 {
1494 nested_size = sizeof (CARD16) * num;
1495 attr_id_list += nested_size;
1496 size -= nested_size;
1497 }
1498 break;
1499 default:
1500 ret = XIM_BadProtocol;
1501 }
1502 if (ret)
1503 return ret;
1504 buf_16 = (CARD16 *) value;
1505 buf_16[0] = GET_CARD16 (attr_id);
1506 buf_16[1] = GET_CARD16 (len);
1507 len = sizeof (CARD16) + /* 2 attribute-id */
1508 sizeof (CARD16) + /* 2 byte length of value */
1509 len + /* n value */
1510 PAD (len); /* p Pad(n) */
1511 value += len;
1512 total += len;
1513 attr_id_list += sizeof (CARD16);
1514 size -= sizeof (CARD16);
1515 }
1516 *size_return = total;
1517 return 0;
1518 }
1519
1520 /*
1521 * Function Name : DecodeIMAttributes()
1522 * Description : decode IM attributes.
1523 * Parameter :
1524 * list : list of IM attribute, packed data.
1525 * size : byte length of list.
1526 * extension : not used.
1527 * Returned Value:
1528 * = 0 : successed.
1529 * > 0 : error, the number is error code.
1530 */
1531 /*ARGSUSED*/ static int
DecodeIMAttributes(list,size,extension)1532 DecodeIMAttributes (list, size, extension)
1533 CARD8 *list;
1534 int size;
1535 XPointer extension; /* for extenstion in future */
1536 {
1537 CARD16 *buf_16;
1538 int ret, len, attr_id;
1539
1540 ret = 0;
1541 while (size > 0)
1542 {
1543 buf_16 = (CARD16 *) list;
1544 attr_id = (int) GET_CARD16 (buf_16[0]);
1545 len = (int) GET_CARD16 (buf_16[1]);
1546 switch (attr_id)
1547 {
1548 case ICInputStyle:
1549 /* we don't allow to set InputStyle so far. */
1550 ret = XIM_BadStyle;
1551 break;
1552 default:
1553 /* no more supported so far */
1554 ret = XIM_BadSomething;
1555 }
1556 if (ret)
1557 return ret;
1558 len += sizeof (CARD16) + /* 2 attribute-id */
1559 sizeof (CARD16) + /* 2 n byte lenght of attr */
1560 len + /* n value of attr */
1561 PAD (len); /* p Pad(n) */
1562 list += len;
1563 size -= len;
1564 }
1565 return 0;
1566 }
1567
1568 /*
1569 * Function Name : SetClientIMValues()
1570 * Description : decode IM values to client context.
1571 * Parameter :
1572 * value : IM values, packed data.
1573 * size : byte length of list.
1574 * im : client IM context.
1575 * Returned Value:
1576 * = 0 : successed.
1577 * > 0 : error, the number is error code.
1578 */
1579 static int
SetClientIMValues(value,size,im)1580 SetClientIMValues (value, size, im)
1581 CARD8 *value;
1582 int size;
1583 XIMContextRec *im;
1584 {
1585 /* no any attribute can be set so far */
1586 return DecodeIMAttributes (value, size, (XPointer) NULL);
1587 }
1588
1589 /*
1590 * Function Name : EncodeInputStyleList()
1591 * Description : encode Input Style list to byte data.
1592 * Parameter :
1593 * im : pointer to client IM context.
1594 * value : encoded byte data.
1595 * size_return : returned byte length of the data.
1596 * Returned Value:
1597 * = 0 : successed.
1598 * > 0 : error, the number is error code.
1599 */
1600 static int
EncodeInputStyleList(im,value,size_return)1601 EncodeInputStyleList (im, value, size_return)
1602 XIMContextRec *im;
1603 CARD8 *value;
1604 int *size_return;
1605 {
1606 CARD16 *buf_16 = (CARD16 *) value;
1607 CARD32 *buf_32 = (CARD32 *) & buf_16[2];
1608 int num, i;
1609
1610 num = MAX_SUPPORT_STYLE - 1;
1611 buf_16[0] = GET_CARD16 (num);
1612 for (i = 0; i <= num; i++)
1613 {
1614 buf_32[i] = GET_CARD32 (xim->supported_style[i]);
1615 }
1616 *size_return = sizeof (CARD16) + /* 2 number of list */
1617 sizeof (CARD16) + /* 2 unused */
1618 sizeof (CARD32) * MAX_SUPPORT_STYLE;
1619 return 0;
1620 }
1621
1622 /*
1623 * Function Name : EncodeIMAttributes()
1624 * Description : encode IM attribute structure to byte data.
1625 * Parameter :
1626 * attr_id_list: list of attribute id.
1627 * size : byte length of the list.
1628 * im : pointer to client IM context.
1629 * value : encoded byte data.
1630 * size_return : returned byte length of the data.
1631 * Returned Value:
1632 * = 0 : successed.
1633 * > 0 : error, the number is error code.
1634 */
1635 static int
EncodeIMAttributes(attr_id_list,size,im,value,size_return)1636 EncodeIMAttributes (attr_id_list, size, im, value, size_return)
1637 CARD8 *attr_id_list;
1638 int size;
1639 XIMContextRec *im;
1640 CARD8 *value;
1641 int *size_return;
1642 {
1643 CARD8 *data;
1644 CARD16 *buf_16;
1645 int ret, len, total, attr_id;
1646
1647 ret = 0;
1648 total = 0;
1649 while (size > 0)
1650 {
1651 buf_16 = (CARD16 *) attr_id_list;
1652 attr_id = (int) GET_CARD16 (buf_16[0]);
1653 data = value + sizeof (CARD16) + sizeof (CARD16);
1654 switch (attr_id)
1655 {
1656 case ICInputStyle:
1657 ret = EncodeInputStyleList (im, data, &len);
1658 break;
1659 default:
1660 ret = XIM_BadSomething;
1661 }
1662 if (ret)
1663 return ret;
1664 buf_16 = (CARD16 *) value;
1665 buf_16[0] = GET_CARD16 (attr_id);
1666 buf_16[1] = GET_CARD16 (len);
1667 len = sizeof (CARD16) + /* 2 attribute-id */
1668 sizeof (CARD16) + /* 2 byte length of value */
1669 len + /* n value */
1670 PAD (len); /* p Pad(n) */
1671 value += len;
1672 total += len;
1673 attr_id_list += sizeof (CARD16);
1674 size -= sizeof (CARD16);
1675 }
1676 *size_return = total;
1677 return 0;
1678 }
1679
1680 /*
1681 * Function Name : CreateClientIC()
1682 * Description : create an IC context and assign a new IC id.
1683 * Parameter :
1684 * im_id : client input-method-id.
1685 * list : list of IC attributes, packed data.
1686 * size : byte length of list.
1687 * ic_id_return: new IC id of the create IC context.
1688 * Returned Value:
1689 * = 0 : successed.
1690 * > 0 : error, the number is error code.
1691 */
1692 static int
CreateClientIC(im_id,list,size,ic_id_return)1693 CreateClientIC (im_id, list, size, ic_id_return)
1694 XIMID im_id;
1695 CARD8 *list;
1696 int size;
1697 XICID *ic_id_return;
1698 {
1699 XIMClientRec *xc;
1700 ximICValuesReq ic_req;
1701 ximICAttributesReq pre_req, st_req;
1702 char *pre_font = (char *) NULL;
1703 char *st_font = (char *) NULL;
1704 XIMNestLangList lc_list = (XIMNestLangList) NULL;
1705 XIMNestLangList cur_lc = (XIMNestLangList) NULL;
1706 XIMNestLangList p;
1707 int have_world = 0, cur_is_world = 0;
1708 char *use_langs, *cur_l, *c_data;
1709 int xic, ret, i;
1710 short detail;
1711 extern XIMClientRec *create_client ();
1712
1713 /*
1714 * parse attributes
1715 */
1716 ret = DecodeICAttributes (list, size, &ic_req, &pre_req, &st_req, &pre_font, &st_font);
1717 if (ret)
1718 return ret;
1719 ic_req.max_keycode = 0; /* set 0 as default */
1720
1721 use_langs = cur_use_lang; /* use locale from XIM_OPEN */
1722 cur_l = (char *) NULL; /* current lang not specified yet. */
1723 c_data = (char *) NULL; /* default user name. */
1724
1725 /* refer to util.c: CreateIC() */
1726
1727 /*
1728 * check resources.
1729 */
1730 if (CheckInputStyle (ic_req.input_style) == False)
1731 return XIM_BadStyle;
1732 if ((ic_req.input_style & (XIMPreeditArea | XIMPreeditPosition)) && (!(ic_req.mask & (1 << ICFontSet)) || !pre_font || !*pre_font))
1733 return XIM_BadName;
1734 if ((ic_req.input_style & XIMStatusArea) && (!(ic_req.mask & (1 << (ICFontSet + StatusOffset))) || !st_font || !*st_font))
1735 return XIM_BadName;
1736 if ((ic_req.input_style & XIMPreeditPosition) && (!(ic_req.mask & (1 << ICSpotLocation))))
1737 return XIM_BadSpotLocation;
1738 if (!(ic_req.input_style & XIMPreeditNothing))
1739 {
1740 if ((have_world = get_langlist (use_langs, &lc_list)) < 0)
1741 {
1742 return XIM_BadAlloc;
1743 }
1744 if (!lc_list)
1745 {
1746 return XIM_LocaleNotSupported;
1747 }
1748 if (cur_l && *cur_l)
1749 {
1750 for (p = lc_list; p != NULL; p = p->next)
1751 {
1752 if (!strcmp (p->lc_name, cur_l) || (p->alias_name && !strcmp (p->alias_name, cur_l)))
1753 break;
1754 }
1755 if (p == NULL)
1756 {
1757 if ((i = get_langlist (cur_l, &cur_lc)) < 0)
1758 {
1759 return XIM_BadAlloc;
1760 }
1761 else if (i > 0)
1762 {
1763 cur_is_world++;
1764 free_langlist (cur_lc);
1765 cur_lc = lc_list;
1766 }
1767 else
1768 {
1769 if (cur_lc)
1770 {
1771 cur_lc->next = lc_list;
1772 }
1773 else
1774 {
1775 cur_lc = lc_list;
1776 }
1777 }
1778 }
1779 else
1780 {
1781 cur_lc = p;
1782 }
1783 }
1784 else
1785 {
1786 if (have_world == 2)
1787 cur_is_world++;
1788 cur_lc = lc_list;
1789 }
1790 }
1791 xc = create_client (&ic_req, &pre_req, &st_req, lc_list, cur_lc, have_world, cur_is_world, pre_font, st_font, c_data, &detail);
1792 if (pre_font)
1793 XFree (pre_font);
1794 if (st_font)
1795 XFree (st_font);
1796 if (lc_list)
1797 free_langlist (lc_list);
1798 if (!xc)
1799 {
1800 return ConvErrorCode (detail);
1801 }
1802 xic = xim->client_count++;
1803 xc->number = xic;
1804 xc->im_id = (int) im_id;
1805 if (IsPreeditNothing (xc))
1806 {
1807 check_root_mapping (xc->root_pointer);
1808 }
1809
1810 *ic_id_return = (XICID) xic;
1811 return 0;
1812 }
1813
1814 /*
1815 * Function Name : CreateIM()
1816 * Description : create a new IM context and register in the list.
1817 * Parameter :
1818 * <none>
1819 * Returned Value:
1820 * > 0 : IM id of the new IM context created.
1821 * = 0 : error
1822 */
1823 static XIMID
CreateIM()1824 CreateIM ()
1825 {
1826 static XIMID base_im_id = BASE_IM_ID;
1827 XIMContextRec *im;
1828
1829 im = (XIMContextRec *) Malloc (sizeof (XIMContextRec));
1830 if (!im)
1831 {
1832 malloc_error ("no memory to open an IM");
1833 return 0;
1834 }
1835 im->im_id = ALLOC_ID (base_im_id);
1836
1837 /* add to IM list */
1838 im->next = ximlist;
1839 ximlist = im;
1840 return im->im_id;
1841 }
1842
1843 /*
1844 * Function Name : GetCompoundTextIndex()
1845 * Description : search the index of string named COMPOUND_TEXT in
1846 * LISTofSTR.
1847 * Parameter :
1848 * list : list of string names LISTofSTR.
1849 * size : byte length of the list.
1850 * Returned Value:
1851 * int : returned index in this list. If not found, it is
1852 * the default XIM_Default_Encoding_IDX.
1853 */
1854 static int
GetCompoundTextIndex(list,size)1855 GetCompoundTextIndex (list, size)
1856 register CARD8 *list;
1857 register int size;
1858 {
1859 register int index, len;
1860
1861 /* get index of COMPOUNT_TEXT which is only supported by us. */
1862 index = 0;
1863 while (size > 0)
1864 {
1865 len = (int) list[0];
1866 if (!strncmp (&list[1], "COMPOUND_TEXT", len))
1867 break;
1868 index++;
1869 list += (sizeof (CARD8) + len);
1870 size -= (sizeof (CARD8) + len);
1871 };
1872 if (size == 0)
1873 index = XIM_Default_Encoding_IDX; /* use default */
1874 return index;
1875 }
1876
1877 /*
1878 * Function Name : FindExtensionByName()
1879 * Description : search an extension item with its name in extension
1880 * list supported by this server.
1881 * Parameter :
1882 * name : ext string name.
1883 * len : length of ext name.
1884 * Returned Value:
1885 * >= 0 : found item index to this list.
1886 * = -1 : not found.
1887 */
1888 static int
FindExtensionByName(name,len)1889 FindExtensionByName (name, len)
1890 char *name;
1891 int len;
1892 {
1893 int ind;
1894
1895 for (ind = 0; ind < XIMNumber (extension_list); ind++)
1896 {
1897 if (!strncmp (extension_list[ind].name, name, len))
1898 return ind;
1899 }
1900 return -1;
1901 }
1902
1903 /*
1904 * Function Name : EncodeExtension()
1905 * Description : encode an extension item to byte data.
1906 * Parameter :
1907 * ind : the item index to extension list.
1908 * value : byte data to store the packed ext item.
1909 * size_return : returned byte size of the packed ext item
1910 * Returned Value:
1911 * = 0 : successed.
1912 * > 0 : error, the number is error code.
1913 */
1914 static int
EncodeExtension(ind,value,size_return)1915 EncodeExtension (ind, value, size_return)
1916 int ind;
1917 CARD8 *value;
1918 int *size_return;
1919 {
1920 CARD16 *buf_16 = (CARD16 *) & value[2];
1921 int len;
1922
1923 len = strlen (extension_list[ind].name);
1924 value[0] = extension_list[ind].major_code;
1925 value[1] = extension_list[ind].minor_code;
1926 buf_16[0] = GET_CARD16 (len);
1927 (void) strncpy ((char *) &buf_16[1], extension_list[ind].name, len);
1928 *size_return = sizeof (CARD8) + /* 1 major_code */
1929 sizeof (CARD8) + /* 1 minor_code */
1930 sizeof (CARD16) + /* 2 n length of name */
1931 len + /* n name */
1932 PAD (len); /* p Pad(n) */
1933 return 0;
1934 }
1935
1936 /*
1937 * Function Name : GetExtensionList()
1938 * Description : get extensions supported by the server.
1939 * Parameter :
1940 * list : list of extension names asked by client.
1941 * size : byte length of the list, if it is zero, client asks
1942 * all extensions supported by the server.
1943 * value : the returned exension names supported by server. It is
1944 * packed in byte.
1945 * size_return : returned byte size of the packed ext names.
1946 * Returned Value:
1947 * = 0 : successed.
1948 * > 0 : error, the number is error code.
1949 */
1950 static int
GetExtensionList(list,size,value,size_return)1951 GetExtensionList (list, size, value, size_return)
1952 CARD8 *list;
1953 int size;
1954 CARD8 *value;
1955 int *size_return;
1956 {
1957 int len, ext_len, ind, total;
1958
1959 total = 0;
1960 if (size == 0)
1961 {
1962 for (ind = 0; ind < XIMNumber (extension_list); ind++)
1963 {
1964 (void) EncodeExtension (ind, value, &ext_len);
1965 value += ext_len;
1966 total += ext_len;
1967 }
1968 }
1969 else
1970 {
1971 while (size > 0)
1972 {
1973 len = (int) list[0];
1974 if ((ind = FindExtensionByName ((char *) &list[1], len)) >= 0)
1975 {
1976 (void) EncodeExtension (ind, value, &ext_len);
1977 value += ext_len;
1978 total += ext_len;
1979 }
1980 list += (sizeof (CARD8) + len);
1981 size -= (sizeof (CARD8) + len);
1982 }
1983 }
1984 *size_return = total;
1985 return 0;
1986 }
1987
1988 /*
1989 * Function Name : RecvRequest()
1990 * Description : receive a request of XIM protocol from IM library.
1991 * Parameter :
1992 * req : pointer to a request structure, returned.
1993 * Returned Value:
1994 * >=0 : byte length of request data except request head.
1995 * < 0 : error in reading data.
1996 */
1997 static int
RecvRequest(req)1998 RecvRequest (req)
1999 XimRequestPacket *req;
2000 {
2001 CARD8 *buf, *read_ptr;
2002 CARD8 byteOrder;
2003 int read_size;
2004 extern char my_byteOrder;
2005
2006 if (_ReadFromClient ((char *) req, XIM_HEADER_SIZE) == -1)
2007 return -1;
2008 if (req->length == 0)
2009 return 0;
2010 read_size = req->length * 4;
2011 read_ptr = buf = MALLOC_REQUEST (read_size);
2012 bzero ((char *) buf, read_size);
2013 if (req->major_opcode == XIM_CONNECT)
2014 {
2015 _ReadFromClient ((char *) &byteOrder, 1);
2016 if (my_byteOrder != (char) byteOrder)
2017 cur_cblk->byteOrder = True;
2018 else
2019 cur_cblk->byteOrder = False;
2020 buf[0] = byteOrder;
2021 read_ptr = &buf[1];
2022 read_size--;
2023 }
2024 if (_ReadFromClient (read_ptr, read_size) == -1)
2025 {
2026 FREE (buf);
2027 return -1;
2028 }
2029 req->data = buf;
2030 return req->length * 4;
2031 }
2032
2033 /*
2034 * Function Name : SendIdOnly()
2035 * Description : send a request that is the format of:
2036 * CARD16 input-method-id
2037 * CARD16 input-context-id
2038 * Parameter :
2039 * im_id : client input-method-id.
2040 * ic_id : client input-context-id.
2041 * major_code : major opcode of this request.
2042 * minor_code : minor opcode of this request.
2043 * Returned Value:
2044 * = 0 : successed.
2045 * > 0 : error, the number is error code.
2046 */
2047 static int
SendIdOnly(im_id,ic_id,major_code,minor_code)2048 SendIdOnly (im_id, ic_id, major_code, minor_code)
2049 XIMID im_id;
2050 XICID ic_id;
2051 CARD8 major_code;
2052 CARD8 minor_code;
2053 {
2054 CARD16 *buf_16;
2055 CARD8 *reply;
2056 int len;
2057
2058 /* reply */
2059 len = sizeof (CARD16) + /* 2 input-method-ID */
2060 sizeof (CARD16); /* 2 input-context-ID */
2061 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2062 len += AddHead (reply, major_code, minor_code, len);
2063 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2064 buf_16[0] = GET_CARD16 (im_id);
2065 buf_16[1] = GET_CARD16 (ic_id);
2066 if (_WriteToClientFlush (reply, len) < 0)
2067 {
2068 FREE (reply);
2069 return XIM_BadSomething;
2070 }
2071 FREE (reply);
2072 return 0;
2073 }
2074
2075 /*
2076 * Function Name : SendSyncReply()
2077 * Description : If server has not syncronized, do sync. Then
2078 * send a XIM_SYNC_REPLY to IM library.
2079 * Parameter :
2080 * im_id : client input-method-id.
2081 * ic_id : client input-context-id.
2082 * Returned Value:
2083 * = 0 : successed.
2084 * > 0 : error, the number is error code.
2085 */
2086 static int
SendSyncReply(im_id,ic_id)2087 SendSyncReply (im_id, ic_id)
2088 XIMID im_id;
2089 XICID ic_id;
2090 {
2091 if (!AllSyncDone (im_id, ic_id))
2092 {
2093 SyncAll (im_id, ic_id);
2094 }
2095 return SendIdOnly (im_id, ic_id, XIM_SYNC_REPLY, 0);
2096 }
2097
2098 /*
2099 * Function Name : RecvSync()
2100 * Description : process of client request XIM_SYNC.
2101 * Parameter :
2102 * req : pointer to a request structure.
2103 * Returned Value:
2104 * = 0 : successed.
2105 * > 0 : error, the number is error code.
2106 */
2107 static int
RecvSync(req)2108 RecvSync (req)
2109 XimRequestPacket *req;
2110 {
2111 CARD16 *buf_16 = (CARD16 *) req->data;
2112 XIMID im_id;
2113 XICID ic_id;
2114
2115 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2116 if (!GetIMWithId (im_id))
2117 return XIM_BadProtocol;
2118
2119 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2120 if (!GetICWithId (ic_id))
2121 return XIM_BadProtocol;
2122
2123 return SendSyncReply (im_id, ic_id);
2124 }
2125
2126 /*
2127 * Function Name : RecvSyncReply()
2128 * Description : process of client request XIM_SYNC_REPLY.
2129 * Parameter :
2130 * req : pointer to a request structure.
2131 * Returned Value:
2132 * = 0 : successed.
2133 * > 0 : error, the number is error code.
2134 */
2135 static int
RecvSyncReply(req)2136 RecvSyncReply (req)
2137 XimRequestPacket *req;
2138 {
2139 /* no action. */
2140 return 0;
2141 }
2142
2143 /*
2144 * Function Name : RecvError()
2145 * Description : process of client request XIM_ERROR.
2146 * Parameter :
2147 * req : pointer to a request structure.
2148 * Returned Value:
2149 * = 0 : successed.
2150 * > 0 : error, the number is error code.
2151 */
2152 static int
RecvError(req)2153 RecvError (req)
2154 XimRequestPacket *req;
2155 {
2156 CARD16 *buf_16 = (CARD16 *) req->data;
2157 XIMID im_id; /* not used yet */
2158 XICID ic_id; /* not used yet */
2159 int eflag, ecode, esnum;
2160
2161 im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2162 ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2163 eflag = (int) GET_CARD16 (buf_16[2]); /* 2 flag */
2164 ecode = (int) GET_CARD16 (buf_16[3]); /* 2 error code */
2165 esnum = (int) GET_CARD16 (buf_16[4]); /* 2 n length */
2166 if (esnum > 0)
2167 {
2168 char *emsg;
2169 if (!(emsg = Malloc (esnum + 1)))
2170 {
2171 return XIM_BadAlloc;
2172 }
2173 (void) strncpy (emsg, (char *) &buf_16[6], esnum);
2174 emsg[esnum] = '\0';
2175 print_out3 ("XIM Protocol Error: %d %s\n", ecode, emsg);
2176 XFree (emsg);
2177 }
2178 else
2179 {
2180 print_out2 ("XIM Protocol Error: %d\n", ecode);
2181 }
2182 return 0;
2183 }
2184
2185 /*
2186 * Function Name : SendError()
2187 * Description : send error message to IM library with the request
2188 * XIM_ERROR.
2189 * Parameter :
2190 * err_code : error code.
2191 * Returned Value:
2192 * <none>
2193 */
2194 static void
SendError(err_code)2195 SendError (err_code)
2196 CARD16 err_code;
2197 {
2198 CARD16 *buf_16;
2199 CARD8 *reply;
2200 int len;
2201
2202 len = sizeof (CARD16) + /* 2 input-method-ID */
2203 sizeof (CARD16) + /* 2 input-context-ID */
2204 sizeof (BITMASK16) + /* 2 flag */
2205 sizeof (CARD16) + /* 2 error code */
2206 sizeof (INT16) + /* 2 byte length of error detail */
2207 sizeof (CARD16); /* 2 type of error detail */
2208 /* empty *//* n error detail */
2209
2210 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2211 len += AddHead (reply, XIM_ERROR, 0, len);
2212 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2213 buf_16[0] = GET_CARD16 (cur_im_id);
2214 buf_16[1] = GET_CARD16 (cur_ic_id);
2215 buf_16[2] = GET_CARD16 (cur_status);
2216 buf_16[3] = GET_CARD16 (err_code);
2217 buf_16[4] = 0; /* no error detail */
2218 buf_16[5] = 0; /* no type */
2219 (void) _WriteToClientFlush (reply, len);
2220 FREE (reply);
2221 }
2222
2223 /*
2224 * Function Name : SendAuthRequired()
2225 * Description : reply XIM_AUTH_REQUIRED as client ask auth.
2226 * Parameter :
2227 * auth_index : index of list of auth names.
2228 * auth_data : auth data.
2229 * length_data : byte length of data.
2230 * Returned Value:
2231 * = 0 : successed.
2232 * > 0 : error, the number is error code.
2233 */
2234 static int
SendAuthRequired(auth_index,auth_data,length_data)2235 SendAuthRequired (auth_index, auth_data, length_data)
2236 CARD8 auth_index;
2237 CARD8 *auth_data;
2238 INT16 length_data;
2239 {
2240 CARD8 *buf_8;
2241 CARD16 *buf_16;
2242 CARD8 *reply;
2243 int len;
2244
2245 len = sizeof (CARD8) + /* 1 auth-protocol_index */
2246 sizeof (CARD8) * 3 + /* 3 unused */
2247 sizeof (CARD16) + /* 2 length of auth data */
2248 sizeof (CARD16) + /* 2 unused */
2249 length_data + /* n data */
2250 PAD (length_data); /* p unused, p = Pad(n) */
2251
2252 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2253 len += AddHead (reply, XIM_AUTH_REQUIRED, 0, len);
2254 buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE);
2255 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4);
2256 buf_8[0] = (CARD8) auth_index;
2257 buf_16[0] = GET_CARD16 (length_data);
2258 if (auth_data && length_data > 0)
2259 {
2260 buf_8 = (CARD8 *) (reply + XIM_HEADER_SIZE + sizeof (CARD8) * 4 + sizeof (CARD16) * 2);
2261 memcpy ((char *) buf_8, (char *) auth_data, length_data);
2262 }
2263 if (_WriteToClientFlush (reply, len) < 0)
2264 {
2265 FREE (reply);
2266 return XIM_BadSomething;
2267 }
2268 FREE (reply);
2269 return 0;
2270 }
2271
2272 /*
2273 * Function Name : SendConnectReply()
2274 * Description : reply connection from IM library.
2275 * Parameter :
2276 * major_version
2277 * : major version of XIM protocol
2278 * minor_version
2279 * : minor version of XIM protocol
2280 * Returned Value:
2281 * = 0 : successed.
2282 * > 0 : error, the number is error code.
2283 */
2284 static int
SendConnectReply(major_version,minor_version)2285 SendConnectReply (major_version, minor_version)
2286 CARD16 major_version;
2287 CARD16 minor_version;
2288 {
2289 CARD16 *buf_16;
2290 CARD8 *reply;
2291 int len;
2292
2293 len = sizeof (CARD16) + /* 2 server-major-protocol-version */
2294 sizeof (CARD16); /* 2 server-minor-protocol-version */
2295 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2296 len += AddHead (reply, XIM_CONNECT_REPLY, 0, len);
2297 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2298 buf_16[0] = GET_CARD16 (major_version);
2299 buf_16[1] = GET_CARD16 (minor_version);
2300 if (_WriteToClientFlush (reply, len) < 0)
2301 {
2302 FREE (reply);
2303 return XIM_BadSomething;
2304 }
2305 FREE (reply);
2306 return 0;
2307 }
2308
2309 /*
2310 * Function Name : RecvConnect()
2311 * Description : do connection with IM client.
2312 * Parameter :
2313 * req : pointer to a request structure.
2314 * Returned Value:
2315 * = 0 : successed.
2316 * > 0 : error, the number is error code.
2317 */
2318 static int
RecvConnect(req)2319 RecvConnect (req)
2320 XimRequestPacket *req;
2321 {
2322 CARD16 *buf_16 = (CARD16 *) (req->data + 2);
2323 CARD16 major_version, minor_version, auth_num;
2324 int len;
2325
2326 len = req->length * 4;
2327 /* we have touched in RecvRequest *//* 1 byte order */
2328 /* not used *//* 1 unused */
2329 major_version = GET_CARD16 (buf_16[0]); /* 2 major protocol version */
2330 minor_version = GET_CARD16 (buf_16[1]); /* 2 minor protocol version */
2331 auth_num = GET_CARD16 (buf_16[2]); /* 2 number of auth. names */
2332
2333 if (major_version != PROTOCOLMAJORVERSION || minor_version != PROTOCOLMINORVERSION)
2334 return XIM_BadProtocol;
2335
2336 len -= sizeof (CARD8) + sizeof (CARD8) + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD16);
2337
2338 if (auth_num > 0)
2339 {
2340 if (GetAuth (&buf_16[3], auth_num, &len, NULL) == False)
2341 {
2342 return XIM_BadSomething; /* error in get auth. */
2343 }
2344 return SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
2345 }
2346 else
2347 {
2348 return SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
2349 }
2350 }
2351
2352 /*
2353 * Function Name : RecvDisconnect()
2354 * Description : disconnect with IM client.
2355 * Parameter :
2356 * req : pointer to a request structure.
2357 * Returned Value:
2358 * = 0 : successed.
2359 * > 0 : error, the number is error code.
2360 */
2361 static int
RecvDisconnect(req)2362 RecvDisconnect (req)
2363 XimRequestPacket *req;
2364 {
2365 CARD8 *reply;
2366 int len;
2367 extern int cur_sock;
2368
2369 close_socket (cur_sock);
2370
2371 /* reply */
2372 len = 0; /* no data */
2373 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2374 len += AddHead (reply, XIM_DISCONNECT_REPLY, 0, len);
2375 if (_WriteToClientFlush (reply, len) < 0)
2376 {
2377 FREE (reply);
2378 return XIM_BadSomething;
2379 }
2380 FREE (reply);
2381 return 0;
2382 }
2383
2384 #ifdef DYNAMIC_EVENT_FLOW_MODEL
2385
2386 /*
2387 * Function Name : SendRegisterTriggerKeys()
2388 * Description : ask client to register trigger keys which will
2389 * turn on or off input method.
2390 * Parameter :
2391 * im_id : client input-method-id.
2392 * Returned Value:
2393 * <none>
2394 */
2395 static void
SendRegisterTriggerKeys(im_id)2396 SendRegisterTriggerKeys (im_id)
2397 XIMID im_id;
2398 {
2399 CARD8 *reply;
2400 CARD16 *buf_16;
2401 CARD32 *buf_32;
2402 CARD32 onkeys[3];
2403 int onkeys_len;
2404 int len;
2405
2406 onkeys[0] = GET_CARD32 (trigger_keys_list[0]);
2407 onkeys[1] = GET_CARD32 (trigger_keys_list[1]);
2408 onkeys[2] = GET_CARD32 (trigger_keys_list[2]);
2409 onkeys_len = sizeof (CARD32) * 3;
2410
2411 /* send */
2412 len = sizeof (CARD16) + /* 2 input-method-ID */
2413 sizeof (CARD16) + /* 2 unused */
2414 sizeof (CARD32) + /* 4 n byte length */
2415 onkeys_len + /* n LISTofXIMTRIGGERKEY */
2416 sizeof (CARD32) + /* 4 m byte length */
2417 onkeys_len; /* m LISTofXIMTRIGGERKEY */
2418
2419 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2420 len += AddHead (reply, XIM_REGISTER_TRIGGERKEYS, 0, len);
2421 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2422 buf_16[0] = GET_CARD16 (im_id);
2423 buf_32 = (CARD32 *) & buf_16[2];
2424 buf_32[0] = GET_CARD32 (onkeys_len);
2425 (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
2426 buf_32 = (CARD32 *) (reply + sizeof (CARD16) + sizeof (CARD16) + sizeof (CARD32) + onkeys_len);
2427 buf_32[0] = GET_CARD32 (onkeys_len); /* off keys same as on-keys */
2428 (void) memcpy ((char *) &buf_32[1], (char *) onkeys, onkeys_len);
2429 (void) _WriteToClientFlush (reply, len);
2430 FREE (reply);
2431 }
2432
2433 /*
2434 * Function Name : ToggleHenkan()
2435 * Description : turn on or off kanji henkan.
2436 */
2437 static void
ToggleHenkan(keys_index,mask)2438 ToggleHenkan (keys_index, mask)
2439 int keys_index;
2440 unsigned long mask;
2441 {
2442 /* not yet */
2443 }
2444
2445 /*
2446 * Function Name : RecvTriggerNotify()
2447 * Description : Some trigger key has pressed by client, it means
2448 * client asks some input method. do it.
2449 * Parameter :
2450 * req : pointer to a request structure.
2451 * Returned Value:
2452 * = 0 : successed.
2453 * > 0 : error, the number is error code.
2454 */
2455 static int
RecvTriggerNotify(req)2456 RecvTriggerNotify (req)
2457 XimRequestPacket *req;
2458 {
2459 CARD16 *buf_16 = (CARD16 *) req->data;
2460 CARD32 *buf_32;
2461 CARD8 *reply;
2462 XIMID im_id;
2463 XICID ic_id;
2464 int len;
2465 int ret, n;
2466 int keys_flag, keys_index;
2467 unsigned long mask;
2468 XIMClientRec *xc;
2469
2470 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2471 if (!GetIMWithId (im_id))
2472 return XIM_BadProtocol;
2473
2474 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2475 if (!(xc = GetICWithId (ic_id)))
2476 return XIM_BadProtocol;
2477
2478 buf_32 = (CARD32 *) & buf_16[2];
2479 keys_flag = (int) GET_CARD32 (buf_32[0]);
2480 keys_index = (int) GET_CARD32 (buf_32[1]);
2481 mask = (unsigned long) GET_CARD32 (buf_32[2]);
2482
2483 if (!keys_flag)
2484 {
2485 /* trigger on */
2486 ToggleHenkan (keys_index, mask);
2487 }
2488 else
2489 {
2490 /* trigger off */
2491 ToggleHenkan (keys_index, mask);
2492 }
2493
2494 /* reply */
2495 return SendIdOnly (im_id, ic_id, XIM_TRIGGER_NOTIFY_REPLY, 0);
2496 }
2497
2498 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
2499
2500 /*
2501 * Function Name : RecvOpen()
2502 * Description : open an IM context for client.
2503 * Parameter :
2504 * req : pointer to a request structure.
2505 * Returned Value:
2506 * = 0 : successed.
2507 * > 0 : error, the number is error code.
2508 */
2509 static int
RecvOpen(req)2510 RecvOpen (req)
2511 XimRequestPacket *req;
2512 {
2513 CARD8 *reply;
2514 CARD16 *buf_16;
2515 XIMID im_id;
2516 int len;
2517
2518 if (_CheckLocaleName (req->data, cur_use_lang) == False)
2519 return XIM_LocaleNotSupported;
2520
2521 if (!(im_id = CreateIM ()))
2522 return XIM_BadAlloc;
2523
2524 #ifdef DYNAMIC_EVENT_FLOW_MODEL
2525 SendRegisterTriggerKeys (im_id);
2526 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
2527
2528 /* reply */
2529 len = sizeof (CARD16) + /* 2 input-method-id */
2530 sizeof (CARD16) + /* 2 byte length of IM attr. */
2531 imattr_list_size + /* n IM attr. supported */
2532 sizeof (CARD16) + /* 2 byte length of IC attr. */
2533 sizeof (CARD16) + /* 2 unused */
2534 icattr_list_size; /* m IC attr. supported */
2535 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2536 len += AddHead (reply, XIM_OPEN_REPLY, 0, len);
2537 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2538 buf_16[0] = GET_CARD16 (im_id);
2539 buf_16[1] = GET_CARD16 (imattr_list_size);
2540 memcpy ((char *) &buf_16[2], (char *) imattr_list, imattr_list_size);
2541
2542 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE + sizeof (CARD16) + sizeof (CARD16) + imattr_list_size);
2543 buf_16[0] = GET_CARD16 (icattr_list_size);
2544 memcpy ((char *) &buf_16[2], (char *) icattr_list, icattr_list_size);
2545
2546 if (_WriteToClientFlush (reply, len) < 0)
2547 {
2548 FREE (reply);
2549 return XIM_BadSomething;
2550 }
2551 FREE (reply);
2552 return 0;
2553 }
2554
2555 /*
2556 * Function Name : RecvClose()
2557 * Description : close an IM client.
2558 * Parameter :
2559 * req : pointer to a request structure.
2560 * Returned Value:
2561 * = 0 : successed.
2562 * > 0 : error, the number is error code.
2563 */
2564 static int
RecvClose(req)2565 RecvClose (req)
2566 XimRequestPacket *req;
2567 {
2568 CARD16 *buf_16 = (CARD16 *) req->data;
2569 CARD8 *reply;
2570 XIMID im_id;
2571 int len;
2572
2573 im_id = cur_im_id = GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2574 if (RemoveIMWithId (im_id) == False)
2575 return XIM_BadProtocol;
2576 cur_im_id = 0;
2577
2578 /* reply */
2579 len = sizeof (CARD16) + /* 2 input-method-ID */
2580 sizeof (CARD16); /* 2 unused */
2581 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2582 len += AddHead (reply, XIM_CLOSE_REPLY, 0, len);
2583 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2584 buf_16[0] = GET_CARD16 (im_id);
2585 if (_WriteToClientFlush (reply, len) < 0)
2586 {
2587 FREE (reply);
2588 return XIM_BadSomething;
2589 }
2590 FREE (reply);
2591 return 0;
2592 }
2593
2594 /*
2595 * Function Name : RecvQueryExtension()
2596 * Description : send extension lists supported by server as the
2597 * client asks.
2598 * Parameter :
2599 * req : pointer to a request structure.
2600 * Returned Value:
2601 * = 0 : successed.
2602 * > 0 : error, the number is error code.
2603 */
2604 static int
RecvQueryExtension(req)2605 RecvQueryExtension (req)
2606 XimRequestPacket *req;
2607 {
2608 CARD16 *buf_16 = (CARD16 *) (req->data);
2609 CARD8 *reply;
2610 XIMID im_id;
2611 CARD8 value[BUFSIZ];
2612 int len, value_len;
2613 int ret, n;
2614
2615 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2616 if (!GetIMWithId (im_id))
2617 {
2618 return XIM_BadProtocol;
2619 }
2620
2621 /* get extetions supported by us. */
2622 n = GET_CARD16 (buf_16[1]); /* 2 n byte length */
2623 ret = GetExtensionList ((CARD8 *) & buf_16[2], n, value, &value_len);
2624 if (ret)
2625 return ret;
2626
2627 /* reply */
2628 len = sizeof (CARD16) + /* 2 input-method-ID */
2629 sizeof (CARD16) + /* 2 n byte length */
2630 value_len; /* n LISTofEXT */
2631 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2632 len += AddHead (reply, XIM_QUERY_EXTENSION_REPLY, 0, len);
2633 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2634 buf_16[0] = GET_CARD16 (im_id);
2635 buf_16[1] = GET_CARD16 (value_len);
2636 (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
2637 if (_WriteToClientFlush (reply, len) < 0)
2638 {
2639 FREE (reply);
2640 return XIM_BadSomething;
2641 }
2642 FREE (reply);
2643 return 0;
2644 }
2645
2646 /*
2647 * Function Name : RecvEncodingNegotiation()
2648 * Description : decide COMPOUND_TEXT as the result of encoding
2649 * negotiation between IM client and server.
2650 * Parameter :
2651 * req : pointer to a request structure.
2652 * Returned Value:
2653 * = 0 : successed.
2654 * > 0 : error, the number is error code.
2655 */
2656 static int
RecvEncodingNegotiation(req)2657 RecvEncodingNegotiation (req)
2658 XimRequestPacket *req;
2659 {
2660 CARD16 *buf_16 = (CARD16 *) req->data;
2661 CARD8 *reply;
2662 XIMID im_id;
2663 int len, n, index;
2664
2665 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2666 if (!GetIMWithId (im_id))
2667 return XIM_BadProtocol;
2668
2669 /* we care only the index of COMPOUNT_TEXT */
2670 n = GET_CARD16 (buf_16[1]); /* 2 byte length */
2671 index = GetCompoundTextIndex ((CARD8 *) & buf_16[2], n);
2672
2673 /* reply */
2674 len = sizeof (CARD16) + /* 2 input-method-ID */
2675 sizeof (CARD16) + /* 2 category of the encoding */
2676 sizeof (CARD16) + /* 2 index of the encoding */
2677 sizeof (CARD16); /* 2 unused */
2678 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2679 len += AddHead (reply, XIM_ENCODING_NEGOTIATION_REPLY, 0, len);
2680 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2681 buf_16[0] = GET_CARD16 (im_id);
2682 buf_16[1] = GET_CARD16 (XIM_Encoding_NameCategory);
2683 buf_16[2] = GET_CARD16 (index);
2684 if (_WriteToClientFlush (reply, len) < 0)
2685 {
2686 FREE (reply);
2687 return XIM_BadSomething;
2688 }
2689 FREE (reply);
2690 return 0;
2691 }
2692
2693 /*
2694 * Function Name : SendSetEventMask()
2695 * Description : send XEvent mask to client which will foward any
2696 * event to the server.
2697 * Parameter :
2698 * req : pointer to a request structure.
2699 * Returned Value:
2700 * <none>
2701 */
2702 static void
SendSetEventMask(im_id,ic_id)2703 SendSetEventMask (im_id, ic_id)
2704 XIMID im_id;
2705 XICID ic_id;
2706 {
2707 CARD8 *reply;
2708 CARD16 *buf_16;
2709 CARD32 *buf_32;
2710 int len;
2711
2712 /* send */
2713 len = sizeof (CARD16) + /* 2 input-method-ID */
2714 sizeof (CARD16) + /* 2 input-context-ID */
2715 sizeof (BITMASK32) + /* 4 forw-event-mask */
2716 sizeof (BITMASK32); /* 4 sync-event-mask */
2717 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2718 len += AddHead (reply, XIM_SET_EVENT_MASK, 0, len);
2719 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2720 buf_16[0] = GET_CARD16 (im_id);
2721 buf_16[1] = GET_CARD16 (ic_id);
2722 buf_32 = (CARD32 *) & buf_16[2];
2723 buf_32[0] = (KeyPressMask | StructureNotifyMask);
2724 buf_32[1] = (KeyPressMask | StructureNotifyMask);
2725 (void) _WriteToClientFlush (reply, len);
2726 FREE (reply);
2727 }
2728
2729 /*
2730 * Function Name : RecvCreateIC()
2731 * Description : create an IC for the connected client.
2732 * Parameter :
2733 * req : pointer to a request structure.
2734 * Returned Value:
2735 * = 0 : successed.
2736 * > 0 : error, the number is error code.
2737 */
2738 static int
RecvCreateIC(req)2739 RecvCreateIC (req)
2740 XimRequestPacket *req;
2741 {
2742 CARD16 *buf_16 = (CARD16 *) req->data;
2743 XIMID im_id;
2744 XICID ic_id;
2745 int ret, len;
2746
2747 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2748 if (!GetIMWithId (im_id))
2749 return XIM_BadProtocol;
2750
2751 /* create IC. */
2752 len = (int) GET_CARD16 (buf_16[1]);
2753 ret = CreateClientIC (im_id, (CARD8 *) & buf_16[2], len, &ic_id);
2754 if (ret)
2755 return ret;
2756 cur_ic_id = ic_id;
2757
2758 /* reply */
2759 ret = SendIdOnly (im_id, ic_id, XIM_CREATE_IC_REPLY, 0);
2760 if (ret)
2761 return ret;
2762
2763 SendSetEventMask (im_id, ic_id);
2764 return 0;
2765 }
2766
2767 /*
2768 * Function Name : RecvSetICValues()
2769 * Description : set IC values to internal client context.
2770 * Parameter :
2771 * req : pointer to a request structure.
2772 * Returned Value:
2773 * = 0 : successed.
2774 * > 0 : error, the number is error code.
2775 */
2776 static int
RecvSetICValues(req)2777 RecvSetICValues (req)
2778 XimRequestPacket *req;
2779 {
2780 CARD16 *buf_16 = (CARD16 *) req->data;
2781 XIMID im_id;
2782 XICID ic_id;
2783 int ret, n;
2784
2785 XIMClientRec *xc;
2786
2787 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2788 if (!GetIMWithId (im_id))
2789 return XIM_BadProtocol;
2790
2791 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2792 if (!(xc = GetICWithId (ic_id)))
2793 return XIM_BadProtocol;
2794
2795 n = (int) GET_CARD16 (buf_16[2]); /* 2 n byte length */
2796 ret = SetClientICValues ((CARD8 *) & buf_16[4], n, xc);
2797 if (ret)
2798 return ret;
2799
2800 /* reply */
2801 return SendIdOnly (im_id, ic_id, XIM_SET_IC_VALUES_REPLY, 0);
2802 }
2803
2804 /*
2805 * Function Name : RecvGetICValues()
2806 * Description : encode IC values of client context, then send to client.
2807 * Parameter :
2808 * req : pointer to a request structure.
2809 * Returned Value:
2810 * = 0 : successed.
2811 * > 0 : error, the number is error code.
2812 */
2813 static int
RecvGetICValues(req)2814 RecvGetICValues (req)
2815 XimRequestPacket *req;
2816 {
2817 CARD16 *buf_16 = (CARD16 *) req->data;
2818 CARD8 *reply;
2819 CARD8 value[BUFSIZ];
2820 XIMID im_id;
2821 XICID ic_id;
2822 int len, value_len, n;
2823 int ret;
2824
2825 XIMClientRec *xc;
2826
2827 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2828 if (!GetIMWithId (im_id))
2829 return XIM_BadProtocol;
2830
2831 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2832 if (!(xc = GetICWithId (ic_id)))
2833 return XIM_BadProtocol;
2834
2835 n = GET_CARD16 (buf_16[2]);
2836 ret = EncodeICAttributes ((CARD8 *) & buf_16[3], n, xc, value, &value_len);
2837 if (ret)
2838 return ret;
2839
2840 /* reply */
2841 len = sizeof (CARD16) + /* 2 input-method-ID */
2842 sizeof (CARD16) + /* 2 input-context-ID */
2843 sizeof (INT16) + /* 2 byte length of ic-attr */
2844 sizeof (CARD16) + /* 2 unused */
2845 value_len; /* n list of ic-attr */
2846
2847 /* reply */
2848 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
2849 len += AddHead (reply, XIM_GET_IC_VALUES_REPLY, 0, len);
2850 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
2851 buf_16[0] = GET_CARD16 (im_id);
2852 buf_16[1] = GET_CARD16 (ic_id);
2853 buf_16[2] = GET_CARD16 (value_len);
2854 (void) memcpy ((char *) &buf_16[4], (char *) value, value_len);
2855 if (_WriteToClientFlush (reply, len) < 0)
2856 {
2857 FREE (reply);
2858 return XIM_BadSomething;
2859 }
2860 FREE (reply);
2861 return 0;
2862 }
2863
2864 /*
2865 * Function Name : JWMline_get()
2866 * Description : put preedit string into a common shared CT buffer which
2867 * can be accessed by GET_COMMON_CT_BUFFER, i.e., "ct_buf".
2868 * Parameter :
2869 * base : beginning position of preedit string.
2870 * pre_len_returned
2871 * : returned length of the string got.
2872 * Returned Value:
2873 * <none>
2874 */
2875 static void
JWMline_get(base,pre_len_returned)2876 JWMline_get (base, pre_len_returned)
2877 int base;
2878 int *pre_len_returned;
2879 {
2880 register XIMLangRec *xl;
2881 register int wc_len, send_len;
2882 register wchar *JW_buf;
2883
2884 *pre_len_returned = 0;
2885 xl = cur_p->cur_xl;
2886 JW_buf = xl->buf + base;
2887 send_len = wc_len = xl->max_pos - base;
2888 if (wc_len > 0)
2889 {
2890 while (1)
2891 {
2892 send_len = wchar_to_ct (cur_p->cur_xl->xlc, JW_buf, ct_buf, wc_len, ct_buf_max);
2893 if (send_len < -1)
2894 {
2895 return;
2896 }
2897 else if (send_len == -1)
2898 {
2899 if (realloc_ct_buf () < 0)
2900 return;
2901 }
2902 else
2903 {
2904 break;
2905 }
2906 }
2907 }
2908 *pre_len_returned = ((send_len >= 0) ? send_len : 0);
2909 }
2910
2911 /*
2912 * Function Name : ResetClientIC()
2913 * Description : reset IC context of client.
2914 * Parameter :
2915 * xc : pointer to client structure.
2916 * pre_str_filled
2917 * : returned preedit string.
2918 * The pre_str_filled parameter is only for readability,
2919 * it is used in a global variable "ct_buf".
2920 * pre_len_returned
2921 * : length of preedit string
2922 * Returned Value:
2923 * = 0 : successed.
2924 * > 0 : error, the number is error code.
2925 */
2926 /*ARGSUSED*/ static int
ResetClientIC(xc,pre_str_filled,pre_len_returned)2927 ResetClientIC (xc, pre_str_filled, pre_len_returned)
2928 XIMClientRec *xc;
2929 unsigned char *pre_str_filled; /* only for readable ct_buf */
2930 int *pre_len_returned;
2931 {
2932 WnnClientRec *save_c_c;
2933 XIMClientRec *save_cur_p, *save_cur_x;
2934 int ret;
2935
2936 /* refer to util.c: ResetIC() */
2937 {
2938 save_c_c = c_c;
2939 save_cur_p = cur_p;
2940 save_cur_x = cur_x;
2941 cur_x = xc;
2942 if (IsPreeditNothing (xc))
2943 {
2944 cur_p = xc->root_pointer->ximclient;
2945 }
2946 else
2947 {
2948 cur_p = cur_x;
2949 }
2950 c_c = cur_p->cur_xl->w_c;
2951 ret = reset_c_b ();
2952 JWMline_get (0, pre_len_returned);
2953 JWMline_clear (0);
2954 c_c = save_c_c;
2955 cur_p = save_cur_p;
2956 cur_x = save_cur_x;
2957 if (ret == -1)
2958 return XIM_BadProtocol;
2959 }
2960 return 0;
2961 }
2962
2963 /*
2964 * Function Name : RecvResetIC()
2965 * Description : reset IC context as client asks.
2966 * Parameter :
2967 * req : pointer to a request structure.
2968 * Returned Value:
2969 * = 0 : successed.
2970 * > 0 : error, the number is error code.
2971 */
2972 static int
RecvResetIC(req)2973 RecvResetIC (req)
2974 XimRequestPacket *req;
2975 {
2976 CARD16 *buf_16 = (CARD16 *) req->data;
2977 CARD8 *reply;
2978 XIMID im_id;
2979 XICID ic_id;
2980 int len, pre_len;
2981 int ret;
2982 unsigned char *pre_str;
2983
2984 XIMClientRec *xc;
2985
2986 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
2987 if (!GetIMWithId (im_id))
2988 return XIM_BadProtocol;
2989
2990 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
2991 if (!(xc = GetICWithId (ic_id)))
2992 return XIM_BadProtocol;
2993
2994 pre_str = GET_SHARED_CT_BUFFER ();
2995 ret = ResetClientIC (xc, pre_str, &pre_len);
2996 if (ret)
2997 return ret;
2998
2999 /* reply */
3000 len = sizeof (CARD16) + /* 2 input-method-ID */
3001 sizeof (CARD16) + /* 2 input-context-ID */
3002 sizeof (INT16) + /* 2 byte length of string */
3003 pre_len + /* n LISTofBYTE */
3004 PAD (sizeof (INT16) + pre_len); /* p Pad(2 + n) */
3005
3006 /* reply */
3007 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3008 len += AddHead (reply, XIM_RESET_IC_REPLY, 0, len);
3009 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3010 buf_16[0] = GET_CARD16 (im_id);
3011 buf_16[1] = GET_CARD16 (ic_id);
3012 buf_16[2] = GET_CARD16 (pre_len);
3013 if (pre_len > 0)
3014 (void) memcpy ((char *) &buf_16[3], (char *) pre_str, pre_len);
3015
3016 if (_WriteToClientFlush (reply, len) < 0)
3017 {
3018 FREE (reply);
3019 return XIM_BadSomething;
3020 }
3021 FREE (reply);
3022 return 0;
3023 }
3024
3025 /*
3026 * Function Name : RecvDestroyIC()
3027 * Description : destroy an IC context.
3028 * Parameter :
3029 * req : pointer to a request structure.
3030 * Returned Value:
3031 * = 0 : successed.
3032 * > 0 : error, the number is error code.
3033 */
3034 static int
RecvDestroyIC(req)3035 RecvDestroyIC (req)
3036 XimRequestPacket *req;
3037 {
3038 CARD16 *buf_16 = (CARD16 *) req->data;
3039 XIMID im_id;
3040 XICID ic_id;
3041
3042 XIMClientRec *xc;
3043
3044 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3045 if (!GetIMWithId (im_id))
3046 return XIM_BadProtocol;
3047
3048 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
3049 if (!(xc = GetICWithId (ic_id)))
3050 return XIM_BadProtocol;
3051 (void) destroy_client (xc);
3052 cur_ic_id = 0;
3053
3054 /* reply */
3055 return SendIdOnly (im_id, ic_id, XIM_DESTROY_IC_REPLY, 0);
3056 }
3057
3058 /*
3059 * Function Name : SetClientICFocus()
3060 * Description : set IC focus to the specified client.
3061 * Parameter :
3062 * xc : pointer to client structure.
3063 * Returned Value:
3064 * = 0 : successed.
3065 * > 0 : error, the number is error code.
3066 */
3067 static int
SetClientICFocus(xc)3068 SetClientICFocus (xc)
3069 XIMClientRec *xc;
3070 {
3071 register XIMInputRec *xi;
3072 XIMClientRec *save_cur_p, *save_cur_x;
3073 WnnClientRec *save_c_c;
3074
3075 /* modified from util.c: SetICFocus() */
3076 {
3077 for (xi = input_list; xi != NULL; xi = xi->next)
3078 {
3079 if (xi->w == xc->focus_window)
3080 break;
3081 }
3082 if (xi == NULL)
3083 {
3084 if (!(xi = (XIMInputRec *) Malloc (sizeof (XIMInputRec))))
3085 {
3086 malloc_error ("allocation of Focus data struct");
3087 return XIM_BadAlloc;
3088 }
3089 xi->w = xc->focus_window;
3090 xi->pclient = xc;
3091 xi->next = NULL;
3092 add_inputlist (xi);
3093 }
3094 save_cur_p = cur_p;
3095 save_cur_x = cur_x;
3096 save_c_c = c_c;
3097 cur_x = xc;
3098 if (IsPreeditNothing (xc))
3099 {
3100 cur_p = xc->root_pointer->ximclient;
3101 }
3102 else
3103 {
3104 cur_p = cur_x;
3105 }
3106 c_c = cur_p->cur_xl->w_c;
3107 cur_rk = c_c->rk;
3108 cur_rk_table = cur_rk->rk_table;
3109 #ifdef CALLBACKS
3110 if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsStatusCallbacks (xc))
3111 {
3112 #else /* CALLBACKS */
3113 if (IsPreeditPosition (xc) || IsPreeditArea (xc))
3114 {
3115 #endif /* CALLBACKS */
3116 reset_preedit (xc);
3117 }
3118 #ifdef CALLBACKS
3119 if (IsStatusArea (xc) || IsStatusCallbacks (xc))
3120 {
3121 #else /* CALLBACKS */
3122 if (IsStatusArea (xc))
3123 {
3124 #endif /* CALLBACKS */
3125 visual_status ();
3126 }
3127 cur_p = save_cur_p;
3128 cur_x = save_cur_x;
3129 c_c = save_c_c;
3130 if (c_c)
3131 {
3132 cur_rk = c_c->rk;
3133 cur_rk_table = cur_rk->rk_table;
3134 }
3135 }
3136 return 0;
3137 }
3138
3139 /*
3140 * Function Name : UnsetClientICFocus()
3141 * Description : unset IC focus to the specified client.
3142 * Parameter :
3143 * xc : pointer to client structure.
3144 * Returned Value:
3145 * = 0 : successed.
3146 * > 0 : error, the number is error code.
3147 */
3148 static int
UnsetClientICFocus(xc)3149 UnsetClientICFocus (xc)
3150 XIMClientRec *xc;
3151 {
3152 register XIMInputRec *xi;
3153 XIMClientRec *save_cur_p, *save_cur_x;
3154 WnnClientRec *save_c_c;
3155
3156 /* modified from util.c: UnsetICFocus() */
3157 {
3158 for (xi = input_list; xi != NULL; xi = xi->next)
3159 {
3160 if (xi->w == xc->focus_window)
3161 break;
3162 }
3163 if (xi == NULL)
3164 {
3165 return XIM_BadFocusWindow;
3166 }
3167 else
3168 {
3169 remove_inputlist (xi);
3170 if (cur_input == xi)
3171 cur_input = 0;
3172 Free ((char *) xi);
3173 save_cur_p = cur_p;
3174 save_cur_x = cur_x;
3175 save_c_c = c_c;
3176 cur_x = xc;
3177 if (IsPreeditNothing (xc))
3178 {
3179 cur_p = xc->root_pointer->ximclient;
3180 }
3181 else
3182 {
3183 cur_p = cur_x;
3184 }
3185 c_c = cur_p->cur_xl->w_c;
3186 cur_rk = c_c->rk;
3187 cur_rk_table = cur_rk->rk_table;
3188 #ifdef CALLBACKS
3189 if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsPreeditCallbacks (xc))
3190 {
3191 #else /* CALLBACKS */
3192 if (IsPreeditPosition (xc) || IsPreeditArea (xc))
3193 {
3194 #endif /* CALLBACKS */
3195 invisual_window ();
3196 }
3197 #ifdef CALLBACKS
3198 if (IsStatusArea (xc) || IsStatusCallbacks (xc))
3199 {
3200 #else /* CALLBACKS */
3201 if (IsStatusArea (xc))
3202 {
3203 #endif /* CALLBACKS */
3204 invisual_status ();
3205 }
3206 cur_p = save_cur_p;
3207 cur_x = save_cur_x;
3208 c_c = save_c_c;
3209 if (c_c)
3210 {
3211 cur_rk = c_c->rk;
3212 cur_rk_table = cur_rk->rk_table;
3213 }
3214 }
3215 }
3216 return 0;
3217 }
3218
3219 /*
3220 * Function Name : RecvSetICFocus()
3221 * Description : set IC focus.
3222 * Parameter :
3223 * req : pointer to a request structure.
3224 * Returned Value:
3225 * = 0 : successed.
3226 * > 0 : error, the number is error code.
3227 */
3228 static int
RecvSetICFocus(req)3229 RecvSetICFocus (req)
3230 XimRequestPacket *req;
3231 {
3232 CARD16 *buf_16 = (CARD16 *) req->data;
3233 XIMID im_id;
3234 XICID ic_id;
3235
3236 XIMClientRec *xc;
3237
3238 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3239 if (!GetIMWithId (im_id))
3240 return XIM_BadProtocol;
3241
3242 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
3243 if (!(xc = GetICWithId (ic_id)))
3244 return XIM_BadProtocol;
3245
3246 return SetClientICFocus (xc);
3247
3248 /* asynchoronous request, no reply */
3249 }
3250
3251 /*
3252 * Function Name : RecvUnsetICFocus()
3253 * Description : unset IC focus.
3254 * Parameter :
3255 * req : pointer to a request structure.
3256 * Returned Value:
3257 * = 0 : successed.
3258 * > 0 : error, the number is error code.
3259 */
3260 static int
RecvUnsetICFocus(req)3261 RecvUnsetICFocus (req)
3262 XimRequestPacket *req;
3263 {
3264 CARD16 *buf_16 = (CARD16 *) req->data;
3265 XIMID im_id;
3266 XICID ic_id;
3267
3268 XIMClientRec *xc;
3269
3270 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3271 if (!GetIMWithId (im_id))
3272 return XIM_BadProtocol;
3273
3274 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
3275 if (!(xc = GetICWithId (ic_id)))
3276 return XIM_BadProtocol;
3277
3278 return UnsetClientICFocus (xc);
3279
3280 /* asynchoronous request, no reply */
3281 }
3282
3283 /*
3284 * Function Name : RecvGetIMValues()
3285 * Description : encode IM values to byte data, then send it to client.
3286 * Parameter :
3287 * req : pointer to a request structure.
3288 * Returned Value:
3289 * = 0 : successed.
3290 * > 0 : error, the number is error code.
3291 */
3292 static int
RecvGetIMValues(req)3293 RecvGetIMValues (req)
3294 XimRequestPacket *req;
3295 {
3296 CARD16 *buf_16 = (CARD16 *) req->data;
3297 CARD8 *reply;
3298 XIMID im_id;
3299 CARD8 value[BUFSIZ];
3300 int len, value_len, n;
3301 int ret;
3302 XIMContextRec *im;
3303
3304 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3305 if (!(im = GetIMWithId (im_id)))
3306 return XIM_BadProtocol;
3307
3308 n = GET_CARD16 (buf_16[1]);
3309 ret = EncodeIMAttributes ((CARD8 *) & buf_16[2], n, im, value, &value_len);
3310 if (ret)
3311 return ret;
3312
3313 /* reply */
3314 len = sizeof (CARD16) + /* 2 input-method-ID */
3315 sizeof (INT16) + /* 2 byte length of im-attr */
3316 value_len; /* n list of im-attr */
3317
3318 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3319 len += AddHead (reply, XIM_GET_IM_VALUES_REPLY, 0, len);
3320 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3321 buf_16[0] = GET_CARD16 (im_id);
3322 buf_16[1] = GET_CARD16 (value_len);
3323 (void) memcpy ((char *) &buf_16[2], (char *) value, value_len);
3324 if (_WriteToClientFlush (reply, len) < 0)
3325 {
3326 FREE (reply);
3327 return XIM_BadSomething;
3328 }
3329 FREE (reply);
3330 return 0;
3331 }
3332
3333 /*
3334 * Function Name : RecvSetIMValues()
3335 * Description : decode IM values, then send it to client context.
3336 * Parameter :
3337 * req : pointer to a request structure.
3338 * Returned Value:
3339 * = 0 : successed.
3340 * > 0 : error, the number is error code.
3341 */
3342 static int
RecvSetIMValues(req)3343 RecvSetIMValues (req)
3344 XimRequestPacket *req;
3345 {
3346 CARD16 *buf_16 = (CARD16 *) req->data;
3347 CARD8 *reply;
3348 XIMID im_id;
3349 int len, n;
3350 int ret;
3351 XIMContextRec *im;
3352
3353 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3354 if (!(im = GetIMWithId (im_id)))
3355 return XIM_BadProtocol;
3356
3357 n = (int) GET_CARD16 (buf_16[1]); /* 2 n byte length */
3358 ret = SetClientIMValues ((CARD8 *) & buf_16[2], n, im);
3359 if (ret)
3360 return ret;
3361
3362 /* reply */
3363 len = sizeof (CARD16) + /* 2 input-method-ID */
3364 sizeof (CARD16); /* 2 unused */
3365 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3366 len += AddHead (reply, XIM_SET_IM_VALUES_REPLY, 0, len);
3367 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3368 buf_16[0] = GET_CARD16 (im_id);
3369 if (_WriteToClientFlush (reply, len) < 0)
3370 {
3371 FREE (reply);
3372 return XIM_BadSomething;
3373 }
3374 FREE (reply);
3375 return 0;
3376 }
3377
3378 /*
3379 * Function Name : SendCommit()
3380 * Description : commit a string to client, the string is converted
3381 * by input method, such kanji, and is encoded in CT.
3382 * Parameter :
3383 * im_id : client input-method-id.
3384 * ic_id : client input-context-id.
3385 * flag : flag of XimLookupKeySym, XimLookupChars or both.
3386 * keysym : keysym if committed.
3387 * ct_str : CT string if committed.
3388 * ct_len : length of string.
3389 * Returned Value:
3390 * = 0 : successed.
3391 * > 0 : error, the number is error code.
3392 */
3393 static int
SendCommit(im_id,ic_id,flag,keysym,ct_str,ct_len)3394 SendCommit (im_id, ic_id, flag, keysym, ct_str, ct_len)
3395 XIMID im_id;
3396 XICID ic_id;
3397 int flag;
3398 KeySym keysym;
3399 char *ct_str;
3400 int ct_len;
3401 {
3402 CARD16 *buf_16;
3403 CARD32 *buf_32;
3404 CARD8 *reply;
3405 int len;
3406
3407 XIMClientRec *xc;
3408
3409 if (!(xc = GetICWithId (ic_id)) || xc->im_id != im_id)
3410 return XIM_BadProtocol;
3411
3412 flag |= XimSYNCHRONUS; /* ask sync */
3413
3414 /* send */
3415 len = sizeof (CARD16) + /* 2 input-method-id */
3416 sizeof (CARD16) + /* 2 input-context-id */
3417 sizeof (BITMASK16) + /* 2 flag */
3418 LENGTH_KEYSYM (flag, sizeof (CARD32)) + /* 2+6 KeySym */
3419 LENGTH_STRING_WITH_FLAG (flag, ct_len); /* 2+n+Pad(2+n) string */
3420
3421 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3422 len += AddHead (reply, XIM_COMMIT, 0, len);
3423 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3424 buf_16[0] = GET_CARD16 (im_id);
3425 buf_16[1] = GET_CARD16 (ic_id);
3426 buf_16[2] = GET_CARD16 (flag);
3427 buf_16 = (CARD16 *) & buf_16[3];
3428 if (flag & XimLookupKeySym)
3429 {
3430 buf_32 = (CARD32 *) & buf_16[1];
3431 buf_32[0] = GET_CARD32 (keysym);
3432 buf_16 = (CARD16 *) & buf_32[1];
3433 }
3434 if (flag & XimLookupChars)
3435 {
3436 buf_16[0] = GET_CARD16 (ct_len);
3437 (void) memcpy ((char *) &buf_16[1], ct_str, ct_len);
3438 }
3439 if (_WriteToClientFlush (reply, len) < 0)
3440 {
3441 FREE (reply);
3442 return XIM_BadSomething;
3443 }
3444 FREE (reply);
3445
3446 if (ClientSyncDone (xc) == True)
3447 return SendSyncReply (im_id, ic_id);
3448 else
3449 return 0;
3450 }
3451
3452 /*
3453 * Function Name : SendForwardEvent()
3454 * Description : usually it is to send event back to client, e.g.
3455 * when no filter in server.
3456 * Parameter :
3457 * im_id : client input-method-id.
3458 * ic_id : client input-context-id.
3459 * serial : serial number of event.
3460 * event : pointer to XEvent.
3461 * Returned Value:
3462 * = 0 : successed.
3463 * > 0 : error, the number is error code.
3464 */
3465 static int
SendForwardEvent(im_id,ic_id,serial,event)3466 SendForwardEvent (im_id, ic_id, serial, event)
3467 XIMID im_id;
3468 XICID ic_id;
3469 int serial;
3470 XEvent *event;
3471 {
3472 CARD16 *buf_16;
3473 CARD8 *reply;
3474 int len;
3475 int flag;
3476
3477 /* send */
3478 len = sizeof (CARD16) + /* 2 input-method-ID */
3479 sizeof (CARD16) + /* 2 input-context-ID */
3480 sizeof (BITMASK16) + /* 2 flag */
3481 sizeof (CARD16) + /* 2 serial number */
3482 sizeof (xEvent); /* n XEVENT */
3483
3484 flag = 0; /* no sync flag */
3485 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3486 len += AddHead (reply, XIM_FORWARD_EVENT, 0, len);
3487 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3488 buf_16[0] = GET_CARD16 (im_id);
3489 buf_16[1] = GET_CARD16 (ic_id);
3490 buf_16[2] = GET_CARD16 (flag);
3491 buf_16[3] = GET_CARD16 (serial);
3492 if (_XimEventToWire (event, (xEvent *) & buf_16[4]) == False)
3493 return XIM_BadSomething;
3494 if (_WriteToClientFlush (reply, len) < 0)
3495 {
3496 FREE (reply);
3497 return XIM_BadSomething;
3498 }
3499 FREE (reply);
3500 return 0;
3501 }
3502
3503 /*
3504 * Function Name : ExecInputMethod()
3505 * Description : execute input method to do some henkan (conversion).
3506 * This is referred to keyin.c: RequestDispatch() on
3507 * the case of XIM_Event.
3508 * Parameter :
3509 * im_id : client input-method-id.
3510 * ic_id : client input-context-id.
3511 * xevp : pointer to event.
3512 * Returned Value:
3513 * = 0 : successed.
3514 * > 0 : error, the number is error code.
3515 */
3516 static int
ExecInputMethod(im_id,ic_id,xevp)3517 ExecInputMethod (im_id, ic_id, xevp)
3518 XIMID im_id;
3519 XICID ic_id;
3520 XEvent *xevp;
3521 {
3522 int buff[32], in;
3523 int ret;
3524 register int i, n_bytes;
3525
3526 ret = key_input (buff, xevp);
3527 if (ret == 0)
3528 {
3529 /* send_nofilter() */
3530 return xim_send_nofilter ();
3531 }
3532 else if (ret > 0)
3533 {
3534 for (i = 0; i < ret;)
3535 {
3536 n_bytes = get_cswidth_by_char (in = buff[i++]);
3537 for (; n_bytes > 1 && i < ret; n_bytes--, i++)
3538 {
3539 in = (in << 8) + buff[i];
3540 }
3541 in_put (in);
3542 }
3543 }
3544 return 0;
3545 }
3546
3547 /*
3548 * Function Name : RecvForwardEvent()
3549 * Description : filter event forwarded by client to execute input
3550 * method.
3551 * Parameter :
3552 * req : pointer to a request structure.
3553 * Returned Value:
3554 * = 0 : successed.
3555 * > 0 : error, the number is error code.
3556 */
3557 static int
RecvForwardEvent(req)3558 RecvForwardEvent (req)
3559 XimRequestPacket *req;
3560 {
3561 CARD16 *buf_16 = (CARD16 *) req->data;
3562 XIMID im_id;
3563 XICID ic_id;
3564 int ret;
3565 int flag, serial;
3566 XEvent event;
3567
3568 XIMClientRec *xc;
3569
3570 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3571 if (!GetIMWithId (im_id))
3572 return XIM_BadProtocol;
3573
3574 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
3575 if (!(xc = GetICWithId (ic_id)))
3576 return XIM_BadProtocol;
3577
3578 flag = (int) GET_CARD16 (buf_16[2]);
3579 serial = (int) GET_CARD16 (buf_16[3]);
3580
3581 SetClientSync (xc, True);
3582
3583 if (_XimWireToEvent (dpy, serial, (xEvent *) & buf_16[4], &event) == False)
3584 return XIM_BadProtocol;
3585 /*
3586 * save event which will back to client if no filter.
3587 */
3588 (void) memcpy ((char *) &(xc->cur_event), (char *) &event, sizeof (XEvent));
3589
3590 ret = ExecInputMethod (im_id, ic_id, &event);
3591 /*
3592 * if it is async (no XimSYNCHRONUS), force 0 returned, so no anything
3593 * even no error is sent to client.
3594 */
3595 if (ret)
3596 return ((flag & XimSYNCHRONUS) ? ret : 0);
3597
3598 if (ClientSyncDone (xc) == True)
3599 return SendSyncReply (im_id, ic_id);
3600 else
3601 return 0;
3602 }
3603
3604 /*
3605 * Function Name : RecvStrConversionReply()
3606 * Description : send a request that is the format of:
3607 * Parameter :
3608 * req : pointer to a request structure.
3609 * Returned Value:
3610 * = 0 : successed.
3611 * > 0 : error, the number is error code.
3612 */
3613 static int
RecvStrConversionReply(req)3614 RecvStrConversionReply (req)
3615 XimRequestPacket *req;
3616 {
3617 /* don't care in this model. */
3618 return 0;
3619 }
3620
3621 #ifdef CALLBACKS
3622
3623 /*
3624 * Function Name : CopyText()
3625 * Description : copy string and feedback array to byte data
3626 * Parameter :
3627 * bur : pointer to the byte data.
3628 * str : string
3629 * feedback : array of feedback.
3630 * feedback_num: number of feedback.
3631 * Returned Value:
3632 * <none>
3633 */
3634 static void
CopyText(buf,str,str_len,feedback,feedback_num)3635 CopyText (buf, str, str_len, feedback, feedback_num)
3636 CARD8 *buf;
3637 char *str;
3638 int str_len;
3639 XIMFeedback *feedback;
3640 int feedback_num;
3641 {
3642 CARD16 *buf_16;
3643 CARD32 *buf_32;
3644 CARD32 *save_32;
3645 BITMASK32 status = 0;
3646 int i;
3647
3648 save_32 = (CARD32 *) buf;
3649 buf_16 = (CARD16 *) & save_32[1];
3650 if (str_len > 0)
3651 {
3652 buf_16[0] = GET_CARD16 (str_len);
3653 (void) strncpy ((char *) &buf_16[1], str, str_len);
3654 buf_16 = (CARD16 *) ((CARD8 *) buf_16 + sizeof (CARD16) + PAD (sizeof (CARD16) + str_len));
3655 }
3656 else
3657 {
3658 status |= XIMNoString;
3659 }
3660 if (feedback_num > 0)
3661 {
3662 buf_16[0] = GET_CARD16 (feedback_num);
3663 buf_32 = (CARD32 *) & buf_16[2];
3664 for (i = 0; i < feedback_num; i++)
3665 {
3666 buf_32[i] = GET_CARD32 (feedback[i]);
3667 }
3668 }
3669 else
3670 {
3671 status |= XIMNoFeedback;
3672 }
3673 save_32[0] = GET_CARD32 (status);
3674 }
3675
3676 /*
3677 * Function Name : SendPreeditDraw()
3678 * Description : send the request of XIM_PREEDT_DRAW.
3679 * Parameter :
3680 * im_id : client input-method-id.
3681 * ic_id : client input-context-id.
3682 * caret : caret
3683 * chg_first : first of change.
3684 * chg_len : length of change.
3685 * str : string.
3686 * str_len : length of string.
3687 * feedback : array of feedback.
3688 * feedback_num: number of feedback.
3689 * Returned Value:
3690 * = 0 : successed.
3691 * > 0 : error, the number is error code.
3692 */
3693 static int
SendPreeditDraw(im_id,ic_id,caret,chg_first,chg_len,str,str_len,feedback,feedback_num)3694 SendPreeditDraw (im_id, ic_id, caret, chg_first, chg_len, str, str_len, feedback, feedback_num)
3695 XIMID im_id;
3696 XICID ic_id;
3697 INT32 caret;
3698 INT32 chg_first;
3699 INT32 chg_len;
3700 char *str;
3701 int str_len;
3702 XIMFeedback *feedback;
3703 int feedback_num;
3704 {
3705 CARD8 *reply;
3706 CARD16 *buf_16;
3707 CARD32 *buf_32;
3708 int len;
3709
3710 /* send */
3711 len = sizeof (CARD16) + /* 2 input-method-ID */
3712 sizeof (CARD16) + /* 2 input-context-ID */
3713 sizeof (INT32) + /* 4 caret */
3714 sizeof (INT32) + /* 4 chg_first */
3715 sizeof (INT32) + /* 4 chg_length */
3716 sizeof (BITMASK32) + /* 4 status */
3717 LENGTH_STRING (str_len) + /* x string */
3718 LENGTH_FEEDBACK (feedback_num); /* x feedback array */
3719
3720 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3721 len += AddHead (reply, XIM_PREEDIT_DRAW, 0, len);
3722 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3723 buf_16[0] = GET_CARD16 (im_id);
3724 buf_16[1] = GET_CARD16 (ic_id);
3725 buf_32 = (CARD32 *) & buf_16[2];
3726 buf_32[0] = GET_CARD32 (caret);
3727 buf_32[1] = GET_CARD32 (chg_first);
3728 buf_32[2] = GET_CARD32 (chg_len);
3729 buf_16 = (CARD16 *) & buf_32[3];
3730 CopyText ((CARD8 *) & buf_32[3], str, str_len, feedback, feedback_num);
3731 if (_WriteToClientFlush (reply, len) < 0)
3732 {
3733 FREE (reply);
3734 return XIM_BadSomething;
3735 }
3736 FREE (reply);
3737 return 0;
3738 }
3739
3740 /*
3741 * Function Name : SendPreeditCaret()
3742 * Description : send the request of XIM_PREEDIT_CARET.
3743 * Parameter :
3744 * im_id : client input-method-id.
3745 * ic_id : client input-context-id.
3746 * pos : position
3747 * direct : direction of caret.
3748 * style : style of caret.
3749 * Returned Value:
3750 * = 0 : successed.
3751 * > 0 : error, the number is error code.
3752 */
3753 static int
SendPreeditCaret(im_id,ic_id,pos,direct,style)3754 SendPreeditCaret (im_id, ic_id, pos, direct, style)
3755 XIMID im_id;
3756 XICID ic_id;
3757 INT32 pos;
3758 CARD32 direct;
3759 CARD32 style;
3760 {
3761 CARD8 *reply;
3762 CARD16 *buf_16;
3763 CARD32 *buf_32;
3764 int len;
3765
3766 /* send */
3767 len = sizeof (CARD16) + /* 2 input-method-ID */
3768 sizeof (CARD16) + /* 2 input-context-ID */
3769 sizeof (INT32) + /* 4 position */
3770 sizeof (CARD32) + /* 4 direction */
3771 sizeof (CARD32); /* 4 style */
3772
3773 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3774 len += AddHead (reply, XIM_PREEDIT_CARET, 0, len);
3775 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3776 buf_16[0] = GET_CARD16 (im_id);
3777 buf_16[1] = GET_CARD16 (ic_id);
3778 buf_32 = (CARD32 *) & buf_16[2];
3779 buf_32[0] = GET_CARD32 (pos);
3780 buf_32[1] = GET_CARD32 (direct);
3781 buf_32[2] = GET_CARD32 (style);
3782 if (_WriteToClientFlush (reply, len) < 0)
3783 {
3784 FREE (reply);
3785 return XIM_BadSomething;
3786 }
3787 FREE (reply);
3788 return 0;
3789 }
3790
3791 /*
3792 * Function Name : SendStatusDraw()
3793 * Description : send the request of XIM_STATUS_DRAW.
3794 * Parameter :
3795 * im_id : client input-method-id.
3796 * ic_id : client input-context-id.
3797 * st_type : type of status.
3798 * str : string.
3799 * str_len : length of string.
3800 * feedback : array of feedback.
3801 * feedback_num: number of feedback.
3802 * pixmap : pixmap data.
3803 * Returned Value:
3804 * = 0 : successed.
3805 * > 0 : error, the number is error code.
3806 */
3807 static int
SendStatusDraw(im_id,ic_id,st_type,str,str_len,feedback,feedback_num,pixmap)3808 SendStatusDraw (im_id, ic_id, st_type, str, str_len, feedback, feedback_num, pixmap)
3809 XIMID im_id;
3810 XICID ic_id;
3811 CARD32 st_type;
3812 char *str;
3813 int str_len;
3814 XIMFeedback *feedback;
3815 int feedback_num;
3816 PIXMAP pixmap;
3817 {
3818 CARD8 *reply;
3819 CARD16 *buf_16;
3820 CARD32 *buf_32;
3821 int len;
3822
3823 /* send */
3824 len = sizeof (CARD16) + /* 2 input-method-ID */
3825 sizeof (CARD16) + /* 2 input-context-ID */
3826 sizeof (CARD32) + /* 4 type */
3827 sizeof (BITMASK32) + /* 4 status */
3828 LENGTH_TEXT (st_type, str_len, feedback_num) + /* text */
3829 LENGTH_PIXMAP (st_type); /* x pixmap */
3830
3831 reply = MALLOC_REPLY (XIM_HEADER_SIZE + len);
3832 len += AddHead (reply, XIM_STATUS_DRAW, 0, len);
3833 buf_16 = (CARD16 *) (reply + XIM_HEADER_SIZE);
3834 buf_16[0] = GET_CARD16 (im_id);
3835 buf_16[1] = GET_CARD16 (ic_id);
3836 buf_32 = (CARD32 *) & buf_16[2];
3837 buf_32[0] = GET_CARD32 (st_type);
3838 if (st_type == XIMTextType)
3839 {
3840 CopyText ((CARD8 *) & buf_32[1], str, str_len, feedback, feedback_num);
3841 }
3842 else
3843 {
3844 buf_32[1] = GET_CARD32 (pixmap);
3845 }
3846 if (_WriteToClientFlush (reply, len) < 0)
3847 {
3848 FREE (reply);
3849 return XIM_BadSomething;
3850 }
3851 FREE (reply);
3852 return 0;
3853 }
3854
3855 /*
3856 * Function Name : RecvPreeditStartReply()
3857 * Description : receive a reply from client.
3858 * Parameter :
3859 * req : pointer to a request structure.
3860 * Returned Value:
3861 * = 0 : successed.
3862 * > 0 : error, the number is error code.
3863 */
3864 static int
RecvPreeditStartReply(req)3865 RecvPreeditStartReply (req)
3866 XimRequestPacket *req;
3867 {
3868 /* don't care. */
3869 return 0;
3870 }
3871
3872 /*
3873 * Function Name : RecvPreeditCaretReply()
3874 * Description : receive a reply from client.
3875 * Parameter :
3876 * req : pointer to a request structure.
3877 * Returned Value:
3878 * = 0 : successed.
3879 * > 0 : error, the number is error code.
3880 */
3881 static int
RecvPreeditCaretReply(req)3882 RecvPreeditCaretReply (req)
3883 XimRequestPacket *req;
3884 {
3885 /* don't care. */
3886 return 0;
3887 }
3888
3889 #endif /* CALLBACKS */
3890
3891 #if defined(EXT_MOVE) || defined(SPOT)
3892
3893 /*
3894 * Function Name : RecvExtMove()
3895 * Description : change only the point of spot.
3896 * Parameter :
3897 * req : pointer to a request structure.
3898 * Returned Value:
3899 * <none>
3900 */
3901 static int
RecvExtMove(req)3902 RecvExtMove (req)
3903 XimRequestPacket *req;
3904 {
3905 CARD16 *buf_16 = (CARD16 *) req->data;
3906 XIMID im_id;
3907 XICID ic_id;
3908 short x, y;
3909 XIMClientRec *xc;
3910
3911 im_id = cur_im_id = (XIMID) GET_CARD16 (buf_16[0]); /* 2 input-method-ID */
3912 if (!GetIMWithId (im_id))
3913 return XIM_BadProtocol;
3914
3915 ic_id = cur_ic_id = (XICID) GET_CARD16 (buf_16[1]); /* 2 input-context-ID */
3916 if (!(xc = GetICWithId (ic_id)))
3917 return XIM_BadProtocol;
3918
3919 x = (short) GET_CARD16 (buf_16[2]);
3920 y = (short) GET_CARD16 (buf_16[3]);
3921 if (change_spotlocation (xc, x, y) != 0)
3922 return XIM_BadSpotLocation;
3923 else
3924 return 0;
3925
3926 /* asynchoronous request, no reply */
3927 }
3928
3929 #endif /* defined(EXT_MOVE) || defined(SPOT) */
3930
3931 /*
3932 * Function Name : AppendServerToProperty()
3933 * Description : append server id to IM_SERVERS property.
3934 * Don't use PropModeAppend that will propagate a same
3935 * server id more and more in the property.
3936 * Parameter :
3937 * disp : pointer to X display.
3938 * win : window that holds the property.
3939 * imserver : our server id to be appended.
3940 * Returned Value:
3941 * True : success.
3942 * False : error.
3943 */
3944 static Bool
AppendServerToProperty(disp,win,imserver)3945 AppendServerToProperty (disp, win, imserver)
3946 Display *disp;
3947 Window win;
3948 Atom imserver;
3949 {
3950 Atom server_atom, actual_type;
3951 Atom *atom_list, *new_list;
3952 int actual_format;
3953 unsigned long nitems, bytes_after;
3954 unsigned char *prop_return;
3955 int i;
3956
3957 server_atom = XInternAtom (disp, XIM_SERVERS, False);
3958 (void) XGetWindowProperty (disp, win, server_atom, 0L, 1000000L, False, XA_ATOM, &actual_type, &actual_format, &nitems, &bytes_after, &prop_return);
3959
3960 if (nitems > 0 && (actual_type != XA_ATOM || actual_format != 32))
3961 {
3962 return False;
3963 }
3964 if (nitems > 0)
3965 {
3966 /*
3967 * search whether our server id has been registered or not.
3968 */
3969 atom_list = (Atom *) prop_return;
3970 for (i = 0; i < nitems; i++)
3971 {
3972 if (atom_list[i] == imserver)
3973 return True;
3974 }
3975 new_list = (Atom *) Malloc ((nitems + 1) * sizeof (Atom));
3976 if (!new_list)
3977 {
3978 malloc_error ("no memory for atom list.");
3979 return False;
3980 }
3981 (void) memcpy ((char *) new_list, (char *) prop_return, nitems * sizeof (Atom));
3982 new_list[nitems] = imserver;
3983 }
3984 else
3985 {
3986 new_list = &imserver;
3987 }
3988
3989 /*
3990 * append our server id to IM_SERVERS property.
3991 */
3992 XChangeProperty (disp, win, server_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *) new_list, (nitems + 1));
3993 if (nitems > 0)
3994 {
3995 XFree ((char *) prop_return);
3996 XFree ((char *) new_list);
3997 }
3998 return True;
3999 }
4000
4001 /*--------------------------------------------------------------------*
4002 * *
4003 * Public Functions *
4004 * *
4005 *--------------------------------------------------------------------*/
4006
4007 /*
4008 * Function Name : XimError()
4009 * Description : take the breakpoint of error when it occurs at any time.
4010 * Parameter :
4011 * fd : socket id of IM client.
4012 * Returned Value:
4013 * <none>
4014 */
4015 #if NeedFunctionPrototypes
4016 void
XimError(int fd)4017 XimError (int fd)
4018 #else
4019 void
4020 XimError (fd)
4021 int fd;
4022 #endif /* NeedFunctionPrototypes */
4023 {
4024 register XIMClientRec *xc;
4025
4026 for (xc = ximclient_list; xc != NULL; xc = xc->next)
4027 {
4028 if (xc->fd == fd)
4029 {
4030 (void) RemoveIMWithId ((XIMID) xc->im_id);
4031 }
4032 }
4033 }
4034
4035 /*
4036 * Function Name : XimRequestDispatch()
4037 * Description : dispatch all requests of X11 IM protocol.
4038 * Parameter :
4039 * <none>
4040 * Returned Value:
4041 * <none>
4042 */
4043 #if NeedFunctionPrototypes
4044 void
XimRequestDispatch(void)4045 XimRequestDispatch (void)
4046 #else
4047 void
4048 XimRequestDispatch ()
4049 #endif /* NeedFunctionPrototypes */
4050 {
4051 XimRequestPacket req_data;
4052 XimRequestPacket *req = &req_data;
4053 int ret;
4054
4055 ret = cur_status = 0;
4056 if (RecvRequest (req) < 0)
4057 return;
4058
4059 /* respond each request of protocol */
4060 switch (req->major_opcode)
4061 {
4062 case XIM_AUTH_NEXT:
4063 ret = SendAuthRequired ((CARD8) 0, (CARD8 *) NULL, (INT16) 0);
4064 break;
4065 case XIM_AUTH_REPLY:
4066 ret = SendConnectReply (PROTOCOLMAJORVERSION, PROTOCOLMINORVERSION);
4067 break;
4068 case XIM_CONNECT:
4069 ret = RecvConnect (req);
4070 break;
4071 case XIM_DISCONNECT:
4072 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4073 ret = RecvDisconnect (req);
4074 break;
4075 case XIM_OPEN:
4076 cur_status = XIM_IMID_VALID;
4077 ret = RecvOpen (req);
4078 break;
4079 case XIM_CLOSE:
4080 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4081 ret = RecvClose (req);
4082 break;
4083 case XIM_ENCODING_NEGOTIATION:
4084 cur_status = XIM_IMID_VALID;
4085 ret = RecvEncodingNegotiation (req);
4086 break;
4087 case XIM_QUERY_EXTENSION:
4088 cur_status = XIM_IMID_VALID;
4089 ret = RecvQueryExtension (req);
4090 break;
4091 case XIM_SET_IM_VALUES:
4092 cur_status = XIM_IMID_VALID;
4093 ret = RecvSetIMValues (req);
4094 break;
4095 case XIM_GET_IM_VALUES:
4096 cur_status = XIM_IMID_VALID;
4097 ret = RecvGetIMValues (req);
4098 break;
4099 case XIM_CREATE_IC:
4100 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4101 ret = RecvCreateIC (req);
4102 break;
4103 case XIM_DESTROY_IC:
4104 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4105 ret = RecvDestroyIC (req);
4106 break;
4107 case XIM_SET_IC_VALUES:
4108 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4109 ret = RecvSetICValues (req);
4110 break;
4111 case XIM_GET_IC_VALUES:
4112 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4113 ret = RecvGetICValues (req);
4114 break;
4115 case XIM_SET_IC_FOCUS:
4116 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4117 (void) RecvSetICFocus (req); /* asyncronous request */
4118 break;
4119 case XIM_UNSET_IC_FOCUS:
4120 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4121 (void) RecvUnsetICFocus (req); /* asyncronous request */
4122 break;
4123 case XIM_TRIGGER_NOTIFY:
4124 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4125 #ifdef DYNAMIC_EVENT_FLOW_MODEL
4126 ret = RecvTriggerNotify (req);
4127 #else
4128 ret = 0;
4129 #endif /* DYNAMIC_EVENT_FLOW_MODEL */
4130 break;
4131 case XIM_FORWARD_EVENT:
4132 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4133 ret = RecvForwardEvent (req);
4134 break;
4135 case XIM_RESET_IC:
4136 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4137 ret = RecvResetIC (req);
4138 break;
4139 case XIM_SYNC:
4140 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4141 ret = RecvSync (req);
4142 break;
4143 case XIM_SYNC_REPLY:
4144 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4145 (void) RecvSyncReply (req); /* don't need send anything */
4146 break;
4147 #ifdef CALLBACKS
4148 case XIM_PREEDIT_START_REPLY:
4149 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4150 ret = RecvPreeditStartReply (req);
4151 break;
4152 case XIM_PREEDIT_CARET_REPLY:
4153 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4154 ret = RecvPreeditCaretReply (req);
4155 break;
4156 #endif /* CALLBACKS */
4157 case XIM_STR_CONVERSION_REPLY:
4158 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4159 ret = RecvStrConversionReply (req);
4160 break;
4161 #if defined(EXT_MOVE) || defined(SPOT)
4162 case XIM_EXT_MOVE:
4163 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4164 (void) RecvExtMove (req); /* asyncronous request */
4165 break;
4166 #endif /* defined(EXT_MOVE) || defined(SPOT) */
4167 case XIM_ERROR:
4168 cur_status = XIM_IMID_VALID | XIM_ICID_VALID;
4169 (void) RecvError (req); /* asyncronous request */
4170 break;
4171 default:
4172 ret = XIM_BadProtocol;
4173 }
4174 if (ret)
4175 SendError (ret);
4176 FREE (req->data);
4177 }
4178
4179 /*
4180 * Function Name : XimPreConnect()
4181 * Description : make a base for preconnection with IM client. This
4182 * includes to create all selection atoms, names and
4183 * properties, plus some initial steps.
4184 * Parameter :
4185 * port : TCP/IP port number used in this IM protocol.
4186 * root : default root client.
4187 * Returned Value:
4188 * = 0 : successed.
4189 * = -1 : error, failed to make preconnection.
4190 */
4191 #if NeedFunctionPrototypes
4192 int
XimPreConnect(unsigned short port,XIMRootRec * root)4193 XimPreConnect (unsigned short port, /* port number 38036/tcp of xwnmo */
4194 XIMRootRec * root)
4195 #else
4196 int
4197 XimPreConnect (port, root)
4198 unsigned short port; /* port number 38036/tcp of xwnmo */
4199 XIMRootRec *root;
4200 #endif /* NeedFunctionPrototypes */
4201 {
4202 char atom_name[BUFFER_MAX];
4203 char hostname[BUFFER_MAX];
4204 int len;
4205
4206 /*
4207 * make server atom: @server=xwnmo
4208 */
4209 (void) sprintf (atom_name, "%s%s", XIM_SERVER_CATEGORY, XIM_SERVER_NAME);
4210 if ((server_id = XInternAtom (dpy, atom_name, True)) != (Atom) None)
4211 {
4212 if (XGetSelectionOwner (dpy, server_id) != (Window) None)
4213 {
4214 print_out ("Another server has been already running.");
4215 return -1;
4216 }
4217 }
4218 else
4219 {
4220 server_id = XInternAtom (dpy, atom_name, False);
4221 }
4222
4223 if (AppendServerToProperty (dpy, root->root_window, server_id) == False)
4224 return -1;
4225
4226 /*
4227 * make target XIM_LOCALES: "@locale=ja,ja_JP,..."
4228 */
4229 (void) strcpy (atom_name, XIM_LOCAL_CATEGORY);
4230 locale_supported = (unsigned char *) GetLocaleSupported ();
4231 len = strlen (atom_name);
4232 if (!(locale_prop = (unsigned char *) Malloc (len + strlen (locale_supported) + 1)))
4233 {
4234 malloc_error ("allocation of locale property");
4235 return -1;
4236 }
4237 locale_target = XInternAtom (dpy, XIM_LOCALES, False);
4238 (void) strcpy (locale_prop, atom_name);
4239 (void) strcat (locale_prop, locale_supported);
4240 locale_supported = locale_prop + len;
4241
4242 /*
4243 * make target XIM_TRANSPORT: "tcp/hostname:port"
4244 */
4245 (void) XmuGetHostname (hostname, (sizeof hostname));
4246 (void) sprintf (atom_name, "%stcp/%s:%u", XIM_TRANSPORT_CATEGORY, hostname, port);
4247 len = strlen (atom_name);
4248 if (!(transport_prop = (unsigned char *) Malloc (len + 1)))
4249 {
4250 malloc_error ("allocation of transport property");
4251 return -1;
4252 }
4253 transport_target = XInternAtom (dpy, XIM_TRANSPORT, False);
4254 (void) strcpy (transport_prop, atom_name);
4255
4256 XSetSelectionOwner (dpy, server_id, root->ximclient->w, 0L);
4257
4258 InitiateProtocol ();
4259
4260 return 0;
4261 }
4262
4263 /*
4264 * Function Name : XimConvertTarget()
4265 * Description : convert a selection target and send its property
4266 * to client. This is in preconnection phase.
4267 * Parameter :
4268 * dpy : pointer to X display.
4269 * event : selection event.
4270 * Returned Value:
4271 * <none>
4272 */
4273 #if NeedFunctionPrototypes
4274 void
XimConvertTarget(Display * dpy,XSelectionRequestEvent * event)4275 XimConvertTarget (Display * dpy, XSelectionRequestEvent * event)
4276 #else
4277 void
4278 XimConvertTarget (dpy, event)
4279 Display *dpy;
4280 XSelectionRequestEvent *event;
4281 #endif /* NeedFunctionPrototypes */
4282 {
4283 XSelectionEvent new;
4284 unsigned char *string = (unsigned char *) NULL;
4285
4286 bzero (&new, sizeof (XSelectionEvent));
4287 new.type = SelectionNotify;
4288 new.serial = event->serial;
4289 new.display = event->display;
4290 new.requestor = event->requestor;
4291 new.selection = event->selection;
4292 new.target = event->target;
4293 new.time = event->time;
4294 new.property = event->property;
4295
4296 if (event->selection == server_id)
4297 {
4298 if (event->target == locale_target)
4299 string = locale_prop;
4300 else if (event->target == transport_target)
4301 string = transport_prop;
4302 if (string)
4303 {
4304 XChangeProperty (dpy, event->requestor, event->property, event->target, 8, PropModeReplace, string, strlen ((char *) string));
4305 XFlush (dpy);
4306 }
4307 }
4308 XSendEvent (dpy, event->requestor, False, NoEventMask, (XEvent *) & new);
4309 }
4310
4311 /*
4312 * Function Name : xim_send_ct()
4313 * Description : similar to Xsi IM send_ct().
4314 * Parameter :
4315 * ct : CT string
4316 * ct_len : length of string in byte.
4317 * Returned Value:
4318 * = 0 : successed.
4319 * > 0 : error, the number is error code.
4320 */
4321 #if NeedFunctionPrototypes
4322 int
xim_send_ct(register char * ct,register int ct_len)4323 xim_send_ct (register char *ct, register int ct_len)
4324 #else
4325 int
4326 xim_send_ct (ct, ct_len)
4327 register char *ct;
4328 register int ct_len;
4329 #endif /* NeedFunctionPrototypes */
4330 {
4331 return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupChars, (KeySym) 0, ct, ct_len);
4332 }
4333
4334 /*
4335 * Function Name : xim_send_keysym()
4336 * Description : similar to Xsi IM send_keysym().
4337 * Parameter :
4338 * keysym : keysym code
4339 * str : keysym character.
4340 * Returned Value:
4341 * = 0 : successed.
4342 * > 0 : error, the number is error code.
4343 */
4344 #if NeedFunctionPrototypes
4345 int
xim_send_keysym(KeySym keysym,char str)4346 xim_send_keysym (KeySym keysym, char str)
4347 #else
4348 int
4349 xim_send_keysym (keysym, str)
4350 KeySym keysym;
4351 char str;
4352 #endif /* NeedFunctionPrototypes */
4353 {
4354 if (keysym < 0x20)
4355 {
4356 keysym |= 0xff00;
4357 return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupKeySym, keysym, (char *) NULL, 0);
4358 }
4359 else
4360 {
4361 str &= 0xff;
4362 return SendCommit (CUR_IM_ID (), CUR_IC_ID (), XimLookupBoth, keysym, &str, 1);
4363 }
4364 }
4365
4366 /*
4367 * Function Name : xim_send_nofilter()
4368 * Description : similar to Xsi IM send_nofilter().
4369 * Parameter :
4370 * <none>
4371 * Returned Value:
4372 * = 0 : successed.
4373 * > 0 : error, the number is error code.
4374 */
4375 #if NeedFunctionPrototypes
4376 int
xim_send_nofilter(void)4377 xim_send_nofilter (void)
4378 #else
4379 int
4380 xim_send_nofilter ()
4381 #endif /* NeedFunctionPrototypes */
4382 {
4383 XEvent *xev = CUR_CLIENT_EVENT ();
4384 int serial = XIM_SERIALNUMBER (((XAnyEvent *) xev)->serial);
4385
4386 return SendForwardEvent (CUR_IM_ID (), CUR_IC_ID (), serial, xev);
4387 }
4388
4389 #ifdef CALLBACKS
4390
4391 /*
4392 * Function Name : xim_send_preeditstart()
4393 * Description : similar to Xsi IM send_preeditstart().
4394 * Parameter :
4395 * <none>
4396 * Returned Value:
4397 * <none>
4398 */
4399 #if NeedFunctionPrototypes
4400 void
xim_send_preeditstart(void)4401 xim_send_preeditstart (void)
4402 #else
4403 void
4404 xim_send_preeditstart ()
4405 #endif /* NeedFunctionPrototypes */
4406 {
4407 (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_START, 0);
4408 }
4409
4410 /*
4411 * Function Name : xim_send_preeditdraw()
4412 * Description : similar to Xsi IM send_preeditdraw().
4413 * Parameter :
4414 * caret : caret
4415 * first : first of change.
4416 * chg_len : length of change.
4417 * str : wchar string.
4418 * len : length of string in wchar.
4419 * flg : flag
4420 * Returned Value:
4421 * <none>
4422 */
4423 #if NeedFunctionPrototypes
4424 void
xim_send_preeditdraw(int caret,int first,int chg_len,wchar * str,int len,int flg)4425 xim_send_preeditdraw (int caret, int first, int chg_len, wchar * str, int len, int flg)
4426 #else
4427 void
4428 xim_send_preeditdraw (caret, first, chg_len, str, len, flg)
4429 int caret;
4430 int first;
4431 int chg_len;
4432 wchar *str;
4433 int len;
4434 int flg;
4435 #endif /* NeedFunctionPrototypes */
4436 {
4437 unsigned short fb = 0;
4438 int send_len;
4439 XIMFeedback xim_fb;
4440
4441 if (str)
4442 {
4443 while (1)
4444 {
4445 send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
4446 if (send_len < -1)
4447 {
4448 return;
4449 }
4450 else if (send_len == -1)
4451 {
4452 if (realloc_ct_buf () < 0)
4453 return;
4454 }
4455 else
4456 {
4457 break;
4458 }
4459 }
4460 }
4461 else
4462 {
4463 send_len = 0;
4464 }
4465 if (flg & REV_FLAG)
4466 fb |= XIMReverse;
4467 if (flg & UNDER_FLAG)
4468 fb |= XIMUnderline;
4469 if (flg & BOLD_FLAG)
4470 fb |= XIMHighlight;
4471
4472 xim_fb = (XIMFeedback) fb;
4473 (void) SendPreeditDraw (CUR_IM_ID (), CUR_IC_ID (), caret, first, chg_len, ct_buf, send_len, (XIMFeedback *) & xim_fb, 1);
4474 }
4475
4476 /*
4477 * Function Name : xim_send_preeditcaret()
4478 * Description : similar to Xsi IM send_preeditcaret().
4479 * Parameter :
4480 * pos : position
4481 * flg : flag
4482 * Returned Value:
4483 * <none>
4484 */
4485 #if NeedFunctionPrototypes
4486 void
xim_send_preeditcaret(int flg,int pos)4487 xim_send_preeditcaret (int flg, int pos)
4488 #else
4489 void
4490 xim_send_preeditcaret (flg, pos)
4491 int flg;
4492 int pos;
4493 #endif /* NeedFunctionPrototypes */
4494 {
4495 int style;
4496
4497 if (flg)
4498 {
4499 style = XIMIsPrimary;
4500 }
4501 else
4502 {
4503 style = XIMIsInvisible;
4504 }
4505 (void) SendPreeditCaret (CUR_IM_ID (), CUR_IC_ID (), pos, XIMAbsolutePosition, style);
4506 }
4507
4508 /*
4509 * Function Name : xim_send_preeditdone()
4510 * Description : similar to Xsi IM send_preeditdone().
4511 * Parameter :
4512 * <none>
4513 * Returned Value:
4514 * <none>
4515 */
4516 #if NeedFunctionPrototypes
4517 void
xim_send_preeditdone(void)4518 xim_send_preeditdone (void)
4519 #else
4520 void
4521 xim_send_preeditdone ()
4522 #endif /* NeedFunctionPrototypes */
4523 {
4524 (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_PREEDIT_DONE, 0);
4525 }
4526
4527 /*
4528 * Function Name : xim_send_statusstart()
4529 * Description : similar to Xsi IM send_statusstart().
4530 * Parameter :
4531 * <none>
4532 * Returned Value:
4533 * <none>
4534 */
4535 #if NeedFunctionPrototypes
4536 void
xim_send_statusstart(void)4537 xim_send_statusstart (void)
4538 #else
4539 void
4540 xim_send_statusstart ()
4541 #endif /* NeedFunctionPrototypes */
4542 {
4543 (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_START, 0);
4544 }
4545
4546 /*
4547 * Function Name : xim_send_statusdraw()
4548 * Description : similar to Xsi IM send_statusdraw().
4549 * Parameter :
4550 * str : wchar string.
4551 * len : length of string in wchar.
4552 * Returned Value:
4553 * <none>
4554 */
4555 #if NeedFunctionPrototypes
4556 void
xim_send_statusdraw(wchar * str,int len)4557 xim_send_statusdraw (wchar * str, int len)
4558 #else
4559 void
4560 xim_send_statusdraw (str, len)
4561 wchar *str;
4562 int len;
4563 #endif /* NeedFunctionPrototypes */
4564 {
4565 int send_len;
4566
4567 /* refer to callback.c: send_statusdraw() */
4568 while (1)
4569 {
4570 send_len = wchar_to_ct (cur_p->cur_xl->xlc, str, ct_buf, len, ct_buf_max);
4571 if (send_len < -1)
4572 {
4573 return;
4574 }
4575 else if (send_len == -1)
4576 {
4577 if (realloc_ct_buf () < 0)
4578 return;
4579 }
4580 else
4581 {
4582 break;
4583 }
4584 }
4585 (void) SendStatusDraw (CUR_IM_ID (), CUR_IC_ID (), XIMTextType, ct_buf, send_len, (XIMFeedback *) NULL, 0, (PIXMAP) 0);
4586 }
4587
4588 /*
4589 * Function Name : xim_send_statusdone()
4590 * Description : similar to Xsi IM send_statusdone().
4591 * Parameter :
4592 * <none>
4593 * Returned Value:
4594 * <none>
4595 */
4596 #if NeedFunctionPrototypes
4597 void
xim_send_statusdone(void)4598 xim_send_statusdone (void)
4599 #else
4600 void
4601 xim_send_statusdone ()
4602 #endif /* NeedFunctionPrototypes */
4603 {
4604 (void) SendIdOnly (CUR_IM_ID (), CUR_IC_ID (), XIM_STATUS_DONE, 0);
4605 }
4606
4607 #endif /* CALLBACKS */
4608
4609 #endif /* !X11R5 */
4610