1 /******************************************************************
3 Copyright 1994, 1995 by Sun Microsystems, Inc.
4 Copyright 1993, 1994 by Hewlett-Packard Company
6 Permission to use, copy, modify, distribute, and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of Sun Microsystems, Inc.
11 and Hewlett-Packard not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior permission.
13 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
14 the suitability of this software for any purpose. It is provided "as is"
15 without express or implied warranty.
17 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
18 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
23 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
28 This version tidied and debugged by Steve Underwood May 1999
30 ******************************************************************/
33 #include <X11/Xatom.h>
37 #include <X11/Xproto.h>
44 extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16);
46 static void *xi18n_setup (Display *, XIMArg *);
47 static Status xi18n_openIM (XIMS);
48 static Status xi18n_closeIM (XIMS);
49 static char *xi18n_setIMValues (XIMS, XIMArg *);
50 static char *xi18n_getIMValues (XIMS, XIMArg *);
51 static Status xi18n_forwardEvent (XIMS, XPointer);
52 static Status xi18n_commit (XIMS, XPointer);
53 static int xi18n_callCallback (XIMS, XPointer);
54 static int xi18n_preeditStart (XIMS, XPointer);
55 static int xi18n_preeditEnd (XIMS, XPointer);
56 static int xi18n_syncXlib (XIMS, XPointer);
59 #define XIM_SERVERS "XIM_SERVERS"
61 static Atom XIM_Servers = None;
64 IMMethodsRec Xi18n_im_methods =
79 extern Bool _Xi18nCheckXAddress (Xi18n, TransportSW *, char *);
80 extern Bool _Xi18nCheckTransAddress (Xi18n, TransportSW *, char *);
82 TransportSW _TransR[] =
84 {"X", 1, _Xi18nCheckXAddress},
86 {"tcp", 3, _Xi18nCheckTransAddress},
87 {"local", 5, _Xi18nCheckTransAddress},
90 {"decnet", 6, _Xi18nCheckTransAddress},
92 {(char *) NULL, 0, (Bool (*) ()) NULL}
95 static Bool GetInputStyles (Xi18n i18n_core, XIMStyles **p_style)
97 Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address;
101 p = &address->input_styles;
102 if ((*p_style = (XIMStyles *) malloc (sizeof (XIMStyles)
103 + p->count_styles*sizeof (XIMStyle)))
109 (*p_style)->count_styles = p->count_styles;
110 (*p_style)->supported_styles = (XIMStyle *) ((XPointer) *p_style + sizeof (XIMStyles));
111 for (i = 0; i < (int) p->count_styles; i++)
112 (*p_style)->supported_styles[i] = p->supported_styles[i];
117 static Bool GetOnOffKeys (Xi18n i18n_core, long mask, XIMTriggerKeys **p_key)
119 Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address;
123 if (mask & I18N_ON_KEYS)
124 p = &address->on_keys;
126 p = &address->off_keys;
128 if ((*p_key = (XIMTriggerKeys *) malloc (sizeof(XIMTriggerKeys)
129 + p->count_keys*sizeof(XIMTriggerKey)))
135 (*p_key)->count_keys = p->count_keys;
137 (XIMTriggerKey *) ((XPointer) *p_key + sizeof(XIMTriggerKeys));
138 for (i = 0; i < (int) p->count_keys; i++)
140 (*p_key)->keylist[i].keysym = p->keylist[i].keysym;
141 (*p_key)->keylist[i].modifier = p->keylist[i].modifier;
142 (*p_key)->keylist[i].modifier_mask = p->keylist[i].modifier_mask;
148 static Bool GetEncodings(Xi18n i18n_core, XIMEncodings **p_encoding)
150 Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address;
154 p = &address->encoding_list;
156 if ((*p_encoding = (XIMEncodings *) malloc (sizeof (XIMEncodings)
157 + p->count_encodings*sizeof(XIMEncoding))) == NULL)
162 (*p_encoding)->count_encodings = p->count_encodings;
163 (*p_encoding)->supported_encodings =
164 (XIMEncoding *) ((XPointer)*p_encoding + sizeof (XIMEncodings));
165 for (i = 0; i < (int) p->count_encodings; i++)
167 (*p_encoding)->supported_encodings[i]
168 = (char *) malloc (strlen (p->supported_encodings[i]) + 1);
169 strcpy ((*p_encoding)->supported_encodings[i],
170 p->supported_encodings[i]);
176 static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
178 Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address;
181 if (mode == I18N_OPEN || mode == I18N_SET)
183 for (p = args; p->name != NULL; p++)
185 if (strcmp (p->name, IMLocale) == 0)
187 if (address->imvalue_mask & I18N_IM_LOCALE)
190 address->im_locale = (char *) malloc (strlen (p->value) + 1);
191 if (!address->im_locale)
194 strcpy (address->im_locale, p->value);
195 address->imvalue_mask |= I18N_IM_LOCALE;
197 else if (strcmp (p->name, IMServerTransport) == 0)
199 if (address->imvalue_mask & I18N_IM_ADDRESS)
200 return IMServerTransport;
202 address->im_addr = (char *) malloc (strlen (p->value) + 1);
203 if (!address->im_addr)
204 return IMServerTransport;
206 strcpy(address->im_addr, p->value);
207 address->imvalue_mask |= I18N_IM_ADDRESS;
209 else if (strcmp (p->name, IMServerName) == 0)
211 if (address->imvalue_mask & I18N_IM_NAME)
214 address->im_name = (char *) malloc (strlen (p->value) + 1);
215 if (!address->im_name)
218 strcpy (address->im_name, p->value);
219 address->imvalue_mask |= I18N_IM_NAME;
221 else if (strcmp (p->name, IMServerWindow) == 0)
223 if (address->imvalue_mask & I18N_IMSERVER_WIN)
224 return IMServerWindow;
226 address->im_window = (Window) p->value;
227 address->imvalue_mask |= I18N_IMSERVER_WIN;
229 else if (strcmp (p->name, IMInputStyles) == 0)
231 if (address->imvalue_mask & I18N_INPUT_STYLES)
232 return IMInputStyles;
234 address->input_styles.count_styles =
235 ((XIMStyles*)p->value)->count_styles;
236 address->input_styles.supported_styles =
237 (XIMStyle *) malloc (sizeof (XIMStyle)*address->input_styles.count_styles);
238 if (address->input_styles.supported_styles == (XIMStyle *) NULL)
239 return IMInputStyles;
241 memmove (address->input_styles.supported_styles,
242 ((XIMStyles *) p->value)->supported_styles,
243 sizeof (XIMStyle)*address->input_styles.count_styles);
244 address->imvalue_mask |= I18N_INPUT_STYLES;
246 else if (strcmp (p->name, IMProtocolHandler) == 0)
248 address->improto = (IMProtoHandler) p->value;
249 address->imvalue_mask |= I18N_IM_HANDLER;
251 else if (strcmp (p->name, IMOnKeysList) == 0)
253 if (address->imvalue_mask & I18N_ON_KEYS)
256 address->on_keys.count_keys =
257 ((XIMTriggerKeys *) p->value)->count_keys;
258 address->on_keys.keylist =
259 (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->on_keys.count_keys);
260 if (address->on_keys.keylist == (XIMTriggerKey *) NULL)
263 memmove (address->on_keys.keylist,
264 ((XIMTriggerKeys *) p->value)->keylist,
265 sizeof (XIMTriggerKey)*address->on_keys.count_keys);
266 address->imvalue_mask |= I18N_ON_KEYS;
268 else if (strcmp (p->name, IMOffKeysList) == 0)
270 if (address->imvalue_mask & I18N_OFF_KEYS)
271 return IMOffKeysList;
273 address->off_keys.count_keys =
274 ((XIMTriggerKeys *) p->value)->count_keys;
275 address->off_keys.keylist =
276 (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->off_keys.count_keys);
277 if (address->off_keys.keylist == (XIMTriggerKey *) NULL)
278 return IMOffKeysList;
280 memmove (address->off_keys.keylist,
281 ((XIMTriggerKeys *) p->value)->keylist,
282 sizeof (XIMTriggerKey)*address->off_keys.count_keys);
283 address->imvalue_mask |= I18N_OFF_KEYS;
285 else if (strcmp (p->name, IMEncodingList) == 0)
287 if (address->imvalue_mask & I18N_ENCODINGS)
288 return IMEncodingList;
290 address->encoding_list.count_encodings =
291 ((XIMEncodings *) p->value)->count_encodings;
292 address->encoding_list.supported_encodings =
293 (XIMEncoding *) malloc (sizeof (XIMEncoding)*address->encoding_list.count_encodings);
294 if (address->encoding_list.supported_encodings
295 == (XIMEncoding *) NULL)
297 return IMEncodingList;
300 memmove (address->encoding_list.supported_encodings,
301 ((XIMEncodings *) p->value)->supported_encodings,
302 sizeof (XIMEncoding)*address->encoding_list.count_encodings);
303 address->imvalue_mask |= I18N_ENCODINGS;
305 else if (strcmp (p->name, IMFilterEventMask) == 0)
307 if (address->imvalue_mask & I18N_FILTERMASK)
308 return IMFilterEventMask;
310 address->filterevent_mask = (long) p->value;
311 address->imvalue_mask |= I18N_FILTERMASK;
316 if (mode == I18N_OPEN)
318 /* check mandatory IM values */
319 if (!(address->imvalue_mask & I18N_IM_LOCALE))
321 /* locales must be set in IMOpenIM */
325 if (!(address->imvalue_mask & I18N_IM_ADDRESS))
327 /* address must be set in IMOpenIM */
328 return IMServerTransport;
334 else if (mode == I18N_GET)
336 for (p = args; p->name != NULL; p++)
338 if (strcmp (p->name, IMLocale) == 0)
340 p->value = (char *) malloc (strlen (address->im_locale) + 1);
344 strcpy (p->value, address->im_locale);
346 else if (strcmp (p->name, IMServerTransport) == 0)
348 p->value = (char *) malloc (strlen (address->im_addr) + 1);
350 return IMServerTransport;
352 strcpy (p->value, address->im_addr);
354 else if (strcmp (p->name, IMServerName) == 0)
356 if (address->imvalue_mask & I18N_IM_NAME)
358 p->value = (char *) malloc (strlen (address->im_name) + 1);
362 strcpy (p->value, address->im_name);
370 else if (strcmp (p->name, IMServerWindow) == 0)
372 if (address->imvalue_mask & I18N_IMSERVER_WIN)
373 *((Window *) (p->value)) = address->im_window;
375 return IMServerWindow;
378 else if (strcmp (p->name, IMInputStyles) == 0)
380 if (GetInputStyles (i18n_core,
381 (XIMStyles **) p->value) == False)
383 return IMInputStyles;
387 else if (strcmp (p->name, IMProtocolHandler) == 0)
389 if (address->imvalue_mask & I18N_IM_HANDLER)
390 *((IMProtoHandler *) (p->value)) = address->improto;
392 return IMProtocolHandler;
395 else if (strcmp (p->name, IMOnKeysList) == 0)
397 if (address->imvalue_mask & I18N_ON_KEYS)
399 if (GetOnOffKeys (i18n_core,
401 (XIMTriggerKeys **) p->value) == False)
413 else if (strcmp (p->name, IMOffKeysList) == 0)
415 if (address->imvalue_mask & I18N_OFF_KEYS)
417 if (GetOnOffKeys (i18n_core,
419 (XIMTriggerKeys **) p->value) == False)
421 return IMOffKeysList;
427 return IMOffKeysList;
431 else if (strcmp (p->name, IMEncodingList) == 0)
433 if (address->imvalue_mask & I18N_ENCODINGS)
435 if (GetEncodings (i18n_core,
436 (XIMEncodings **) p->value) == False)
438 return IMEncodingList;
444 return IMEncodingList;
448 else if (strcmp (p->name, IMFilterEventMask) == 0)
450 if (address->imvalue_mask & I18N_FILTERMASK)
451 *((long *) (p->value)) = address->filterevent_mask;
453 return IMFilterEventMask;
464 static int CheckIMName (Xi18n i18n_core)
466 char *address = i18n_core->address.im_addr;
469 for (i = 0; _TransR[i].transportname; i++)
471 while (*address == ' ' || *address == '\t')
474 if (strncmp (address,
475 _TransR[i].transportname,
476 _TransR[i].namelen) == 0
478 address[_TransR[i].namelen] == '/')
480 if (_TransR[i].checkAddr (i18n_core,
482 address + _TransR[i].namelen + 1) == True)
495 static int SetXi18nSelectionOwner(Xi18n i18n_core)
497 Display *dpy = i18n_core->address.dpy;
498 Window ims_win = i18n_core->address.im_window;
499 Window root = RootWindow (dpy, DefaultScreen (dpy));
502 unsigned long bytesafter;
504 unsigned long length;
511 (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name);
512 if ((atom = XInternAtom(dpy, buf, False)) == 0)
514 i18n_core->address.selection = atom;
516 if (XIM_Servers == None)
517 XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False);
519 XGetWindowProperty (dpy,
530 (unsigned char **) (&data));
531 if (realtype != None && (realtype != XA_ATOM || realformat != 32)) {
533 XFree ((char *) data);
538 for (i = 0; i < length; i++) {
539 if (data[i] == atom) {
542 if ((owner = XGetSelectionOwner (dpy, atom)) != ims_win) {
543 if (owner == None || forse == True)
544 XSetSelectionOwner (dpy, atom, ims_win, CurrentTime);
552 if (found == False) {
553 XSetSelectionOwner (dpy, atom, ims_win, CurrentTime);
554 XChangeProperty (dpy,
560 (unsigned char *) &atom,
565 * We always need to generate the PropertyNotify to the Root Window
567 XChangeProperty (dpy,
573 (unsigned char *) data,
577 XFree ((char *) data);
579 /* Intern "LOCALES" and "TRANSOPORT" Target Atoms */
580 i18n_core->address.Localename = XInternAtom (dpy, LOCALES, False);
581 i18n_core->address.Transportname = XInternAtom (dpy, TRANSPORT, False);
582 return (XGetSelectionOwner (dpy, atom) == ims_win);
585 static int DeleteXi18nAtom(Xi18n i18n_core)
587 Display *dpy = i18n_core->address.dpy;
588 Window root = RootWindow (dpy, DefaultScreen (dpy));
591 unsigned long bytesafter;
593 unsigned long length;
599 (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name);
600 if ((atom = XInternAtom(dpy, buf, False)) == 0)
602 i18n_core->address.selection = atom;
604 if (XIM_Servers == None)
605 XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False);
606 XGetWindowProperty (dpy,
617 (unsigned char **) (&data));
618 if (realtype != XA_ATOM || realformat != 32) {
620 XFree ((char *) data);
625 for (i = 0; i < length; i++) {
626 if (data[i] == atom) {
633 for (i=i+1; i<length; i++)
635 XChangeProperty (dpy,
641 (unsigned char *)data,
646 XChangeProperty (dpy,
652 (unsigned char *)data,
657 XFree ((char *) data);
662 /* XIM protocol methods */
663 static void *xi18n_setup (Display *dpy, XIMArg *args)
668 if ((i18n_core = (Xi18n) malloc (sizeof (Xi18nCore))) == (Xi18n) NULL)
672 memset (i18n_core, 0, sizeof (Xi18nCore));
674 i18n_core->address.dpy = dpy;
676 if (ParseArgs (i18n_core, I18N_OPEN, args) != NULL)
682 if (*(char *) &endian)
683 i18n_core->address.im_byteOrder = 'l';
685 i18n_core->address.im_byteOrder = 'B';
688 /* install IMAttr and ICAttr list in i18n_core */
689 _Xi18nInitAttrList (i18n_core);
691 /* install IMExtension list in i18n_core */
692 _Xi18nInitExtension (i18n_core);
697 static void ReturnSelectionNotify (Xi18n i18n_core, XSelectionRequestEvent *ev)
700 Display *dpy = i18n_core->address.dpy;
703 event.type = SelectionNotify;
704 event.xselection.requestor = ev->requestor;
705 event.xselection.selection = ev->selection;
706 event.xselection.target = ev->target;
707 event.xselection.time = ev->time;
708 event.xselection.property = ev->property;
709 if (ev->target == i18n_core->address.Localename)
711 snprintf (buf, 4096, "@locale=%s", i18n_core->address.im_locale);
713 else if (ev->target == i18n_core->address.Transportname)
715 snprintf (buf, 4096, "@transport=%s", i18n_core->address.im_addr);
718 XChangeProperty (dpy,
719 event.xselection.requestor,
724 (unsigned char *) buf,
726 XSendEvent (dpy, event.xselection.requestor, False, NoEventMask, &event);
727 XFlush (i18n_core->address.dpy);
730 static Bool WaitXSelectionRequest (Display *dpy,
733 XPointer client_data)
735 XIMS ims = (XIMS) client_data;
736 Xi18n i18n_core = ims->protocol;
738 if (((XSelectionRequestEvent *) ev)->selection
739 == i18n_core->address.selection)
741 ReturnSelectionNotify (i18n_core, (XSelectionRequestEvent *) ev);
748 static Status xi18n_openIM(XIMS ims)
750 Xi18n i18n_core = ims->protocol;
751 Display *dpy = i18n_core->address.dpy;
753 if (!CheckIMName (i18n_core)
755 !SetXi18nSelectionOwner (i18n_core)
757 !i18n_core->methods.begin (ims))
759 XFree (i18n_core->address.im_name);
760 XFree (i18n_core->address.im_locale);
761 XFree (i18n_core->address.im_addr);
767 _XRegisterFilterByType (dpy,
768 i18n_core->address.im_window,
771 WaitXSelectionRequest,
777 static Status xi18n_closeIM(XIMS ims)
779 Xi18n i18n_core = ims->protocol;
780 Display *dpy = i18n_core->address.dpy;
782 DeleteXi18nAtom(i18n_core);
783 if (!i18n_core->methods.end (ims))
786 _XUnregisterFilter (dpy,
787 i18n_core->address.im_window,
788 WaitXSelectionRequest,
790 XFree (i18n_core->address.im_name);
791 XFree (i18n_core->address.im_locale);
792 XFree (i18n_core->address.im_addr);
797 static char *xi18n_setIMValues (XIMS ims, XIMArg *args)
799 Xi18n i18n_core = ims->protocol;
802 if ((ret = ParseArgs (i18n_core, I18N_SET, args)) != NULL)
808 static char *xi18n_getIMValues (XIMS ims, XIMArg *args)
810 Xi18n i18n_core = ims->protocol;
813 if ((ret = ParseArgs (i18n_core, I18N_GET, args)) != NULL)
819 static void EventToWireEvent (XEvent *ev, xEvent *event,
820 CARD16 *serial, Bool byte_swap)
823 extern XimFrameRec wire_keyevent_fr[];
824 extern XimFrameRec short_fr[];
829 *serial = (CARD16)(ev->xany.serial >> 16);
834 XKeyEvent *kev = (XKeyEvent*)ev;
835 /* create FrameMgr */
836 fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap);
839 b = (BYTE)kev->type; FrameMgrPutToken(fm, b);
840 b = (BYTE)kev->keycode; FrameMgrPutToken(fm, b);
841 c16 = (CARD16)(kev->serial & (unsigned long)0xffff);
842 FrameMgrPutToken(fm, c16);
843 c32 = (CARD32)kev->time; FrameMgrPutToken(fm, c32);
844 c32 = (CARD32)kev->root; FrameMgrPutToken(fm, c32);
845 c32 = (CARD32)kev->window; FrameMgrPutToken(fm, c32);
846 c32 = (CARD32)kev->subwindow; FrameMgrPutToken(fm, c32);
847 c16 = (CARD16)kev->x_root; FrameMgrPutToken(fm, c16);
848 c16 = (CARD16)kev->y_root; FrameMgrPutToken(fm, c16);
849 c16 = (CARD16)kev->x; FrameMgrPutToken(fm, c16);
850 c16 = (CARD16)kev->y; FrameMgrPutToken(fm, c16);
851 c16 = (CARD16)kev->state; FrameMgrPutToken(fm, c16);
852 b = (BYTE)kev->same_screen; FrameMgrPutToken(fm, b);
856 /* create FrameMgr */
857 fm = FrameMgrInit(short_fr, (char *)(&(event->u.u.sequenceNumber)),
859 c16 = (CARD16)(ev->xany.serial & (unsigned long)0xffff);
860 FrameMgrPutToken(fm, c16);
867 static Status xi18n_forwardEvent (XIMS ims, XPointer xp)
869 Xi18n i18n_core = ims->protocol;
870 IMForwardEventStruct *call_data = (IMForwardEventStruct *)xp;
872 extern XimFrameRec forward_event_fr[];
873 register int total_size;
874 unsigned char *reply = NULL;
875 unsigned char *replyp;
880 client = (Xi18nClient *) _Xi18nFindClient (i18n_core, call_data->connect_id);
882 /* create FrameMgr */
883 fm = FrameMgrInit (forward_event_fr,
885 _Xi18nNeedSwap (i18n_core, call_data->connect_id));
887 total_size = FrameMgrGetTotalSize (fm);
888 event_size = sizeof (xEvent);
889 reply = (unsigned char *) malloc (total_size + event_size);
892 _Xi18nSendMessage (ims,
893 call_data->connect_id,
901 memset (reply, 0, total_size + event_size);
902 FrameMgrSetBuffer (fm, reply);
905 call_data->sync_bit = 1; /* always sync */
908 FrameMgrPutToken (fm, call_data->connect_id);
909 FrameMgrPutToken (fm, call_data->icid);
910 FrameMgrPutToken (fm, call_data->sync_bit);
912 replyp += total_size;
913 EventToWireEvent (&(call_data->event),
916 _Xi18nNeedSwap (i18n_core, call_data->connect_id));
918 FrameMgrPutToken (fm, serial);
920 _Xi18nSendMessage (ims,
921 call_data->connect_id,
925 total_size + event_size);
933 static Status xi18n_commit (XIMS ims, XPointer xp)
935 Xi18n i18n_core = ims->protocol;
936 IMCommitStruct *call_data = (IMCommitStruct *)xp;
938 extern XimFrameRec commit_chars_fr[];
939 extern XimFrameRec commit_both_fr[];
940 register int total_size;
941 unsigned char *reply = NULL;
944 call_data->flag |= XimSYNCHRONUS; /* always sync */
946 if (!(call_data->flag & XimLookupKeySym)
948 (call_data->flag & XimLookupChars))
950 fm = FrameMgrInit (commit_chars_fr,
952 _Xi18nNeedSwap (i18n_core, call_data->connect_id));
954 /* set length of STRING8 */
955 str_length = strlen (call_data->commit_string);
956 FrameMgrSetSize (fm, str_length);
957 total_size = FrameMgrGetTotalSize (fm);
958 reply = (unsigned char *) malloc (total_size);
961 _Xi18nSendMessage (ims,
962 call_data->connect_id,
970 memset (reply, 0, total_size);
971 FrameMgrSetBuffer (fm, reply);
973 str_length = FrameMgrGetSize (fm);
974 FrameMgrPutToken (fm, call_data->connect_id);
975 FrameMgrPutToken (fm, call_data->icid);
976 FrameMgrPutToken (fm, call_data->flag);
977 FrameMgrPutToken (fm, str_length);
978 FrameMgrPutToken (fm, call_data->commit_string);
982 fm = FrameMgrInit (commit_both_fr,
984 _Xi18nNeedSwap (i18n_core, call_data->connect_id));
985 /* set length of STRING8 */
986 str_length = strlen (call_data->commit_string);
988 FrameMgrSetSize (fm, str_length);
990 total_size = FrameMgrGetTotalSize (fm);
991 reply = (unsigned char *) malloc (total_size);
994 _Xi18nSendMessage (ims,
995 call_data->connect_id,
1003 FrameMgrSetBuffer (fm, reply);
1004 FrameMgrPutToken (fm, call_data->connect_id);
1005 FrameMgrPutToken (fm, call_data->icid);
1006 FrameMgrPutToken (fm, call_data->flag);
1007 FrameMgrPutToken (fm, call_data->keysym);
1010 str_length = FrameMgrGetSize (fm);
1011 FrameMgrPutToken (fm, str_length);
1012 FrameMgrPutToken (fm, call_data->commit_string);
1018 _Xi18nSendMessage (ims,
1019 call_data->connect_id,
1030 static int xi18n_callCallback (XIMS ims, XPointer xp)
1032 IMProtocol *call_data = (IMProtocol *)xp;
1033 switch (call_data->major_code)
1036 return _Xi18nGeometryCallback (ims, call_data);
1038 case XIM_PREEDIT_START:
1039 return _Xi18nPreeditStartCallback (ims, call_data);
1041 case XIM_PREEDIT_DRAW:
1042 return _Xi18nPreeditDrawCallback (ims, call_data);
1044 case XIM_PREEDIT_CARET:
1045 return _Xi18nPreeditCaretCallback (ims, call_data);
1047 case XIM_PREEDIT_DONE:
1048 return _Xi18nPreeditDoneCallback (ims, call_data);
1050 case XIM_STATUS_START:
1051 return _Xi18nStatusStartCallback (ims, call_data);
1053 case XIM_STATUS_DRAW:
1054 return _Xi18nStatusDrawCallback (ims, call_data);
1056 case XIM_STATUS_DONE:
1057 return _Xi18nStatusDoneCallback (ims, call_data);
1059 case XIM_STR_CONVERSION:
1060 return _Xi18nStringConversionCallback (ims, call_data);
1066 /* preeditStart and preeditEnd are used only for Dynamic Event Flow. */
1067 static int xi18n_preeditStart (XIMS ims, XPointer xp)
1069 IMProtocol *call_data = (IMProtocol *)xp;
1070 Xi18n i18n_core = ims->protocol;
1071 IMPreeditStateStruct *preedit_state =
1072 (IMPreeditStateStruct *) &call_data->preedit_state;
1074 int on_key_num = i18n_core->address.on_keys.count_keys;
1075 int off_key_num = i18n_core->address.off_keys.count_keys;
1077 if (on_key_num == 0 && off_key_num == 0)
1080 if (i18n_core->address.imvalue_mask & I18N_FILTERMASK)
1081 mask = i18n_core->address.filterevent_mask;
1083 mask = DEFAULT_FILTER_MASK;
1085 _Xi18nSetEventMask (ims,
1086 preedit_state->connect_id,
1087 preedit_state->connect_id,
1088 preedit_state->icid,
1094 static int xi18n_preeditEnd (XIMS ims, XPointer xp)
1096 IMProtocol *call_data = (IMProtocol *)xp;
1097 Xi18n i18n_core = ims->protocol;
1098 int on_key_num = i18n_core->address.on_keys.count_keys;
1099 int off_key_num = i18n_core->address.off_keys.count_keys;
1100 IMPreeditStateStruct *preedit_state;
1102 preedit_state = (IMPreeditStateStruct *) &call_data->preedit_state;
1104 if (on_key_num == 0 && off_key_num == 0)
1108 _Xi18nSetEventMask (ims,
1109 preedit_state->connect_id,
1110 preedit_state->connect_id,
1111 preedit_state->icid,
1117 static int xi18n_syncXlib (XIMS ims, XPointer xp)
1119 IMProtocol *call_data = (IMProtocol *)xp;
1120 Xi18n i18n_core = ims->protocol;
1121 IMSyncXlibStruct *sync_xlib;
1123 extern XimFrameRec sync_fr[];
1125 CARD16 connect_id = call_data->any.connect_id;
1127 unsigned char *reply;
1129 sync_xlib = (IMSyncXlibStruct *) &call_data->sync_xlib;
1130 fm = FrameMgrInit (sync_fr, NULL,
1131 _Xi18nNeedSwap (i18n_core, connect_id));
1132 total_size = FrameMgrGetTotalSize(fm);
1133 reply = (unsigned char *) malloc (total_size);
1135 _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
1138 memset (reply, 0, total_size);
1139 FrameMgrSetBuffer (fm, reply);
1141 /* input input-method ID */
1142 FrameMgrPutToken (fm, connect_id);
1143 /* input input-context ID */
1144 FrameMgrPutToken (fm, sync_xlib->icid);
1145 _Xi18nSendMessage (ims, connect_id, XIM_SYNC, 0, reply, total_size);