1 /*
2  * $Id: util.c,v 1.2 2001/06/14 18:16:17 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  * Copyright 1991, 1992 by Massachusetts Institute of Technology
11  *
12  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU Emacs; see the file COPYING.  If not, write to the
26  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  * Commentary:
29  *
30  * Change log:
31  *
32  * Last modified date: 8,Feb.1999
33  *
34  * Code:
35  *
36  */
37 /*      Version 4.0
38  */
39 #include <stdio.h>
40 #include "commonhd.h"
41 #include "sdefine.h"
42 #include "xim.h"
43 #include "sheader.h"
44 #include "proto.h"
45 #include "ext.h"
46 
47 static int c_data_len = 0, use_langs_len = 0, cur_l_len = 0;
48 static int pre_font_len = 0, st_font_len = 0;
49 static char *c_data = NULL, *use_langs = NULL, *cur_l = NULL;
50 static char *pre_font = NULL, *st_font = NULL;
51 
52 void
GetIM()53 GetIM ()
54 {
55   ximGetIMReq req;
56   ximGetIMReply reply;
57   unsigned long mask;
58   int i;
59   XIMStyle tmp;
60   int tmp_num_styles, tmp_nbytes;
61 
62   if (EACH_REQUEST (&req, sz_ximGetIMReq) == -1)
63     return;
64   if (need_byteswap () == True)
65     {
66       mask = byteswap_l (req.mask);
67     }
68   else
69     {
70       mask = req.mask;
71     }
72   reply.state = 0;
73   if (mask & (1 << IMQueryInputStyle))
74     {
75       reply.num_styles = MAX_SUPPORT_STYLE;
76     }
77   else
78     {
79       reply.num_styles = 0;
80     }
81   if (mask & (1 << IMQueryLanguage))
82     {
83       reply.nbytes = strlen (xim->supported_language);
84     }
85   else
86     {
87       reply.nbytes = 0;
88     }
89   tmp_num_styles = reply.num_styles;
90   tmp_nbytes = reply.nbytes;
91   if (need_byteswap () == True)
92     {
93       byteswap_GetIMReply (&reply);
94     }
95   if (_WriteToClient (&reply, sz_ximGetIMReply) == -1)
96     return;
97   if (tmp_num_styles > 0)
98     {
99       for (i = 0; i < MAX_SUPPORT_STYLE; i++)
100         {
101           if (need_byteswap () == True)
102             {
103               tmp = byteswap_l (xim->supported_style[i]);
104             }
105           else
106             {
107               tmp = xim->supported_style[i];
108             }
109           if (_WriteToClient (&tmp, sizeof (XIMStyle)) == -1)
110             {
111               return;
112             }
113         }
114     }
115   if (tmp_nbytes > 0)
116     {
117       if (_WriteToClient (xim->supported_language, tmp_nbytes) == -1)
118         {
119           return;
120         }
121     }
122   if (_Send_Flush () == -1)
123     return;
124   return;
125 }
126 
127 /* *INDENT-OFF* */
128 Status
have_world(lc_list)129 have_world (lc_list)
130     XIMNestLangList lc_list;
131 /* *INDENT-ON* */
132 
133 {
134   XIMNestLangList p = lc_list;
135 
136   for (; p != NULL; p = p->next)
137     {
138       if (!strcmp (p->lc_name, world_locale))
139         return (True);
140     }
141   return (False);
142 }
143 
144 void
CreateIC()145 CreateIC ()
146 {
147   ximICValuesReq ic_req;
148   ximICAttributesReq pre_req, st_req;
149   ximCreateICReply reply;
150 #ifdef  CALLBACKS
151   ximEventReply reply1;
152 #endif /* CALLBACKS */
153   int c_len;
154   XIMNestLangList p;
155   XIMNestLangList lc_list = NULL, cur_lc = NULL;
156   XIMClientRec *xc = NULL;
157   int error = 0;
158   int i, ret;
159   short detail;
160   int have_world = 0, cur_is_world = 0;
161 
162   c_len = get_rest_len ();
163   if ((ret = read_strings (&c_data, &c_data_len, c_len)) < 0)
164     {
165       if (ret == -1)
166         return;
167       error++;
168     }
169 
170   if (_ReadFromClient (&ic_req, sz_ximICValuesReq) == -1)
171     return;
172   if (need_byteswap () == True)
173     {
174       byteswap_ICValuesReq (&ic_req);
175     }
176   if ((ret = read_strings (&use_langs, &use_langs_len, ic_req.nbytes)) < 0)
177     {
178       if (ret == -1)
179         return;
180       error++;
181     }
182   if ((ret = read_strings (&cur_l, &cur_l_len, ic_req.nbytes2)) < 0)
183     {
184       if (ret == -1)
185         return;
186       error++;
187     }
188 
189   if (_ReadFromClient (&pre_req, sz_ximICAttributesReq) == -1)
190     return;
191   if (need_byteswap () == True)
192     {
193       byteswap_ICAttributesReq (&pre_req);
194     }
195   if ((ret = read_strings (&pre_font, &pre_font_len, pre_req.nbytes)) < 0)
196     {
197       if (ret == -1)
198         return;
199       error++;
200     }
201 
202   if (_ReadFromClient (&st_req, sz_ximICAttributesReq) == -1)
203     return;
204   if (need_byteswap () == True)
205     {
206       byteswap_ICAttributesReq (&st_req);
207     }
208   if ((ret = read_strings (&st_font, &st_font_len, st_req.nbytes)) < 0)
209     {
210       if (ret == -1)
211         return;
212       error++;
213     }
214   if (error > 0)
215     {
216       detail = AllocError;
217       goto ERROR_RET;
218     }
219 
220   /*
221    * Check resources.
222    */
223   error = -1;
224   if ((ic_req.mask & (1 << ICInputStyle)))
225     {
226       for (i = 0; i < MAX_SUPPORT_STYLE; i++)
227         {
228           if (xim->supported_style[i] == ic_req.input_style)
229             {
230               error = 0;
231               break;
232             }
233         }
234     }
235   if (error != 0)
236     {
237       detail = BadStyle;
238     }
239   else
240     {
241       if (ic_req.input_style & (XIMPreeditArea | XIMPreeditPosition))
242         {
243           if (!(ic_req.mask & (1 << ICFontSet)) || !pre_font || !*pre_font)
244             {
245               error = -1;
246               detail = BadFontSet;
247             }
248         }
249       if (ic_req.input_style & XIMStatusArea)
250         {
251           if (!(ic_req.mask & (1 << (ICFontSet + StatusOffset))) || !st_font || !*st_font)
252             {
253               error = -1;
254               detail = BadFontSet;
255             }
256         }
257       if (ic_req.input_style & XIMPreeditPosition)
258         {
259           if (!(ic_req.mask & (1 << ICSpotLocation)))
260             {
261               error = -1;
262               detail = BadSpotLocation;
263             }
264         }
265     }
266   if (error == -1)
267     goto ERROR_RET;
268 
269   if (!(ic_req.input_style & XIMPreeditNothing))
270     {
271       if ((have_world = get_langlist (use_langs, &lc_list)) < 0)
272         {
273           error = -1;
274           detail = AllocError;
275           goto ERROR_RET;
276         }
277       if (!lc_list)
278         {
279           error = -1;
280           detail = BadLanguage;
281           goto ERROR_RET;
282         }
283       if (cur_l && *cur_l)
284         {
285           for (p = lc_list; p != NULL; p = p->next)
286             {
287               if (!strcmp (p->lc_name, cur_l) || (p->alias_name && !strcmp (p->alias_name, cur_l)))
288                 break;
289             }
290           if (p == NULL)
291             {
292               if ((i = get_langlist (cur_l, &cur_lc)) < 0)
293                 {
294                   error = -1;
295                   detail = AllocError;
296                   goto ERROR_RET;
297                 }
298               else if (i > 0)
299                 {
300                   cur_is_world++;
301                   free_langlist (cur_lc);
302                   cur_lc = lc_list;
303                 }
304               else
305                 {
306                   if (cur_lc)
307                     {
308                       cur_lc->next = lc_list;
309                     }
310                   else
311                     {
312                       cur_lc = lc_list;
313                     }
314                 }
315             }
316           else
317             {
318               cur_lc = p;
319             }
320         }
321       else
322         {
323           if (have_world == 2)
324             cur_is_world++;
325           cur_lc = lc_list;
326         }
327     }
328   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);
329   free_langlist (lc_list);
330 
331 ERROR_RET:
332   if (error != 0 || xc == NULL)
333     {
334       reply.state = -1;
335       reply.detail = detail;
336       reply.xic = 0;
337     }
338   else
339     {
340       reply.state = 0;
341       reply.xic = xim->client_count++;
342       xc->number = reply.xic;
343     }
344 #ifdef  CALLBACKS
345   reply1.state = 0;
346   reply1.detail = XIM_IC;
347   if (need_byteswap () == True)
348     {
349       byteswap_EventReply (&reply1);
350       byteswap_CreateICReply (&reply);
351     }
352   if ((_WriteToClient (&reply1, sz_ximEventReply) == -1) || (_WriteToClient (&reply, sz_ximCreateICReply) == -1) ||
353 #else /* CALLBACKS */
354   if (need_byteswap () == True)
355     {
356       byteswap_CreateICReply (&reply);
357     }
358   if ((_WriteToClient (&reply, sz_ximCreateICReply) == -1) ||
359 #endif /* CALLBACKS */
360       (_Send_Flush () == -1))
361     {
362       return;
363     }
364   if (xc && IsPreeditNothing (xc))
365     {
366       check_root_mapping (xc->root_pointer);
367     }
368   return;
369 }
370 
371 void
GetIC()372 GetIC ()
373 {
374   ximGetICReq req;
375   ximGetICReply reply;
376   ximICValuesReq reply1;
377   ximICAttributesReq reply2;
378   register XIMClientRec *xc;
379   register XIMRootRec *root;
380   unsigned long mask = 0L;
381   XIMAttributes *pe, *st;
382   int tmp_nbytes, tmp_nbytes2;
383 
384   if (EACH_REQUEST (&req, sz_ximGetICReq) == -1)
385     return;
386   if (need_byteswap () == True)
387     {
388       req.mask = byteswap_l (req.mask);
389       req.xic = byteswap_l (req.xic);
390     }
391   mask = req.mask;
392 
393   for (xc = ximclient_list; xc != NULL; xc = xc->next)
394     {
395       if (xc->number == req.xic)
396         {
397           break;
398         }
399     }
400   if (xc == NULL)
401     {
402       reply.state = -1;
403       reply.detail = BadIC;
404       if (need_byteswap () == True)
405         {
406           byteswap_GetICReply (&reply);
407         }
408       if (_WriteToClient (&reply, sz_ximGetICReply) == -1)
409         return;
410       return;
411     }
412   else
413     {
414       reply.state = 0;
415     }
416   if (need_byteswap () == True)
417     {
418       byteswap_GetICReply (&reply);
419     }
420   if (_WriteToClient (&reply, sz_ximGetICReply) == -1)
421     return;
422 #ifdef  CALLBACKS
423 /*
424     if (IsPreeditNothing(xc)) {
425         xc = xc->root_pointer->ximclient;
426     }
427 */
428 #endif /* CALLBACKS */
429 
430   root = xc->root_pointer;
431   reply1.mask = mask;
432 
433   if (mask & (1 << ICInputStyle))
434     {
435       reply1.input_style = xc->input_style;
436     }
437   if (mask & (1 << ICClientWindow))
438     {
439       reply1.c_window = xc->w;
440     }
441   if (mask & (1 << ICFocusWindow))
442     {
443       reply1.focus_window = xc->focus_window;
444     }
445   if (mask & (1 << ICFilterEvents))
446     {
447       reply1.filter_events = xc->filter_events;
448     }
449   if (mask & (1 << ICUsingLanguage))
450     {
451       if (IsPreeditNothing (xc))
452         {
453           reply1.nbytes = strlen (root->ximclient->using_language);
454         }
455       else if (xc->using_language)
456         {
457           reply1.nbytes = strlen (xc->using_language);
458         }
459       else
460         {
461           reply1.nbytes = 0;
462         }
463     }
464   else
465     {
466       reply1.nbytes = 0;
467     }
468   if (mask & (1 << ICCurrentLanguage))
469     {
470       if (IsPreeditNothing (xc))
471         {
472           if (root->ximclient->world_on)
473             {
474               reply1.nbytes2 = strlen (world_locale);
475             }
476           else
477             {
478               reply1.nbytes2 = strlen (root->ximclient->cur_xl->cur_lc->lc_name);
479             }
480         }
481       else if (xc->world_on)
482         {
483           reply1.nbytes2 = strlen (world_locale);
484         }
485       else if (xc->cur_xl->cur_lc->lc_name)
486         {
487           reply1.nbytes2 = strlen (xc->cur_xl->cur_lc->lc_name);
488         }
489       else
490         {
491           reply1.nbytes2 = 0;
492         }
493 /*
494     if ((mask & (1 << ICCurrentLanguage)) && !IsPreeditNothing(xc)
495         && xc->cur_xl->cur_lc->lc_name) {
496         reply1.nbytes2 = strlen(xc->cur_xl->cur_lc->lc_name);
497 */
498     }
499   else
500     {
501       reply1.nbytes2 = 0;
502     }
503   tmp_nbytes = reply1.nbytes;
504   tmp_nbytes2 = reply1.nbytes2;
505   if (need_byteswap () == True)
506     {
507       byteswap_ICValuesReq (&reply1);
508     }
509   if (_WriteToClient (&reply1, sz_ximICValuesReq) == -1)
510     return;
511   if (tmp_nbytes > 0)
512     {
513       if (IsPreeditNothing (xc))
514         {
515           if (_WriteToClient (root->ximclient->using_language, tmp_nbytes) == -1)
516             return;
517         }
518       else
519         {
520           if (_WriteToClient (xc->using_language, tmp_nbytes) == -1)
521             return;
522         }
523     }
524   if (tmp_nbytes2 > 0)
525     {
526       if (IsPreeditNothing (xc))
527         {
528           if (root->ximclient->world_on)
529             {
530               if (_WriteToClient (world_locale, tmp_nbytes2) == -1)
531                 return;
532             }
533           else
534             {
535               if (_WriteToClient (root->ximclient->cur_xl->cur_lc->lc_name, tmp_nbytes2) == -1)
536                 return;
537             }
538         }
539       else
540         {
541           if (xc->world_on)
542             {
543               if (_WriteToClient (world_locale, tmp_nbytes2) == -1)
544                 return;
545             }
546           else
547             {
548               if (_WriteToClient (xc->cur_xl->cur_lc->lc_name, tmp_nbytes2) == -1)
549                 return;
550             }
551         }
552     }
553 
554   pe = &(xc->pe);
555   if (mask & (1 << ICArea))
556     {
557       reply2.area_x = pe->area.x;
558       reply2.area_y = pe->area.y;
559       reply2.area_width = pe->area.width;
560       reply2.area_height = pe->area.height;
561     }
562   if (mask & (1 << ICAreaNeeded))
563     {
564       reply2.areaneeded_width = pe->area_needed.width;
565       reply2.areaneeded_height = pe->area_needed.height;
566     }
567   if (IsPreeditPosition (xc))
568     {
569       if (mask & (1 << ICSpotLocation))
570         {
571           reply2.spot_x = xc->point.x;
572           reply2.spot_y = xc->point.y + FontAscent (xc->cur_xl);
573         }
574     }
575   if (mask & (1 << ICColormap))
576     {
577       reply2.colormap = pe->colormap;
578     }
579   if (mask & (1 << ICStdColormap))
580     {
581       reply2.std_colormap = pe->std_colormap;
582     }
583   if (mask & (1 << ICForeground))
584     {
585       reply2.foreground = pe->fg;
586     }
587   if (mask & (1 << ICBackground))
588     {
589       reply2.background = pe->bg;
590     }
591   if (mask & (1 << ICBackgroundPixmap))
592     {
593       reply2.pixmap = pe->bg_pixmap;
594     }
595   if (mask & (1 << ICLineSpace))
596     {
597       reply2.line_space = pe->line_space;
598     }
599   if (mask & (1 << ICCursor))
600     {
601       reply2.cursor = pe->cursor;
602     }
603   reply2.nfonts = 0;
604   reply2.nbytes = 0;
605   if (need_byteswap () == True)
606     {
607       byteswap_ICAttributesReq (&reply2);
608     }
609   if (_WriteToClient (&reply2, sz_ximICAttributesReq) == -1)
610     return;
611 
612   st = &(xc->st);
613   if (mask & (1 << (ICArea + StatusOffset)))
614     {
615       reply2.area_x = st->area.x;
616       reply2.area_y = st->area.y;
617       reply2.area_width = st->area.width;
618       reply2.area_height = st->area.height;
619     }
620   if (mask & (1 << (ICAreaNeeded + StatusOffset)))
621     {
622       reply2.areaneeded_width = st->area_needed.width;
623       reply2.areaneeded_height = st->area_needed.height;
624     }
625   if (mask & (1 << (ICColormap + StatusOffset)))
626     {
627       reply2.colormap = st->colormap;
628     }
629   if (mask & (1 << (ICStdColormap + StatusOffset)))
630     {
631       reply2.std_colormap = st->std_colormap;
632     }
633   if (mask & (1 << (ICForeground + StatusOffset)))
634     {
635       reply2.foreground = st->fg;
636     }
637   if (mask & (1 << (ICBackground + StatusOffset)))
638     {
639       reply2.background = st->bg;
640     }
641   if (mask & (1 << (ICBackgroundPixmap + StatusOffset)))
642     {
643       reply2.pixmap = st->bg_pixmap;
644     }
645   if (mask & (1 << (ICLineSpace + StatusOffset)))
646     {
647       reply2.line_space = st->line_space;
648     }
649   if (mask & (1 << (ICCursor + StatusOffset)))
650     {
651       reply2.cursor = st->cursor;
652     }
653   reply2.nfonts = 0;
654   reply2.nbytes = 0;
655   if (need_byteswap () == True)
656     {
657       byteswap_ICAttributesReq (&reply2);
658     }
659   if (_WriteToClient (&reply2, sz_ximICAttributesReq) == -1)
660     return;
661   if (_Send_Flush () == -1)
662     return;
663 }
664 
665 void
SetICFocus()666 SetICFocus ()
667 {
668   ximICFocusReq req;
669   ximEventReply reply;
670   register XIMClientRec *xc;
671   register XIMInputRec *xi;
672   XIMClientRec *save_cur_p, *save_cur_x;
673   WnnClientRec *save_c_c;
674 
675   if (EACH_REQUEST (&req, sz_ximICFocusReq) == -1)
676     return;
677   if (need_byteswap () == True)
678     {
679       req.xic = byteswap_l (req.xic);
680     }
681 
682   for (xc = ximclient_list; xc != NULL; xc = xc->next)
683     {
684       if (xc->number == req.xic)
685         break;
686     }
687   if (xc == NULL)
688     {
689       reply.state = -1;
690       reply.detail = BadIC;
691     }
692   else
693     {
694       for (xi = input_list; xi != NULL; xi = xi->next)
695         {
696           if (xi->w == xc->focus_window)
697             break;
698         }
699       if (xi == NULL)
700         {
701           if (!(xi = (XIMInputRec *) Malloc (sizeof (XIMInputRec))))
702             {
703               malloc_error ("allocation of Focus data struct");
704               reply.state = -1;
705               reply.detail = AllocError;
706               goto ERROR_RET;
707             }
708           xi->w = xc->focus_window;
709           xi->pclient = xc;
710           xi->next = NULL;
711           add_inputlist (xi);
712         }
713       save_cur_p = cur_p;
714       save_cur_x = cur_x;
715       save_c_c = c_c;
716       cur_x = xc;
717       if (IsPreeditNothing (xc))
718         {
719           cur_p = xc->root_pointer->ximclient;
720         }
721       else
722         {
723           cur_p = cur_x;
724         }
725       c_c = cur_p->cur_xl->w_c;
726       cur_rk = c_c->rk;
727       cur_rk_table = cur_rk->rk_table;
728 #ifdef  CALLBACKS
729       if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsStatusCallbacks (xc))
730         {
731 #else /* CALLBACKS */
732       if (IsPreeditPosition (xc) || IsPreeditArea (xc))
733         {
734 #endif /* CALLBACKS */
735           reset_preedit (xc);
736         }
737 #ifdef  CALLBACKS
738       if (IsStatusArea (xc) || IsStatusCallbacks (xc))
739         {
740 #else /* CALLBACKS */
741       if (IsStatusArea (xc))
742         {
743 #endif /* CALLBACKS */
744           visual_status ();
745         }
746       cur_p = save_cur_p;
747       cur_x = save_cur_x;
748       c_c = save_c_c;
749       if (c_c)
750         {
751           cur_rk = c_c->rk;
752           cur_rk_table = cur_rk->rk_table;
753         }
754       reply.state = 0;
755       reply.detail = 0;
756     }
757 ERROR_RET:
758   if (need_byteswap () == True)
759     {
760       byteswap_EventReply (&reply);
761     }
762   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
763     return;
764   return;
765 }
766 
767 void
768 UnsetICFocus ()
769 {
770   ximICFocusReq req;
771   ximEventReply reply;
772   register XIMClientRec *xc;
773   register XIMInputRec *xi;
774   XIMClientRec *save_cur_p, *save_cur_x;
775   WnnClientRec *save_c_c;
776 
777   if (EACH_REQUEST (&req, sz_ximICFocusReq) == -1)
778     return;
779   if (need_byteswap () == True)
780     {
781       req.xic = byteswap_l (req.xic);
782     }
783 
784   for (xc = ximclient_list; xc != NULL; xc = xc->next)
785     {
786       if (xc->number == req.xic)
787         break;
788     }
789   if (xc == NULL)
790     {
791       reply.state = -1;
792       reply.detail = BadIC;
793     }
794   else
795     {
796       for (xi = input_list; xi != NULL; xi = xi->next)
797         {
798           if (xi->w == xc->focus_window)
799             break;
800         }
801       if (xi == NULL)
802         {
803           reply.state = -1;
804           reply.detail = BadFocusWindow;
805         }
806       else
807         {
808           remove_inputlist (xi);
809           if (cur_input == xi)
810             cur_input = 0;
811           Free ((char *) xi);
812           save_cur_p = cur_p;
813           save_cur_x = cur_x;
814           save_c_c = c_c;
815           cur_x = xc;
816           if (IsPreeditNothing (xc))
817             {
818               cur_p = xc->root_pointer->ximclient;
819             }
820           else
821             {
822               cur_p = cur_x;
823             }
824           c_c = cur_p->cur_xl->w_c;
825           cur_rk = c_c->rk;
826           cur_rk_table = cur_rk->rk_table;
827 #ifdef  CALLBACKS
828           if (IsPreeditPosition (xc) || IsPreeditArea (xc) || IsPreeditCallbacks (xc))
829             {
830 #else /* CALLBACKS */
831           if (IsPreeditPosition (xc) || IsPreeditArea (xc))
832             {
833 #endif /* CALLBACKS */
834               invisual_window ();
835             }
836 #ifdef  CALLBACKS
837           if (IsStatusArea (xc) || IsStatusCallbacks (xc))
838             {
839 #else /* CALLBACKS */
840           if (IsStatusArea (xc))
841             {
842 #endif /* CALLBACKS */
843               invisual_status ();
844             }
845           cur_p = save_cur_p;
846           cur_x = save_cur_x;
847           c_c = save_c_c;
848           if (c_c)
849             {
850               cur_rk = c_c->rk;
851               cur_rk_table = cur_rk->rk_table;
852             }
853           reply.state = 0;
854           reply.detail = 0;
855         }
856     }
857   if (need_byteswap () == True)
858     {
859       byteswap_EventReply (&reply);
860     }
861   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
862     return;
863   return;
864 }
865 
866 void
867 ChangeIC ()
868 {
869   register XIMClientRec *xc;
870   XIMNestLangRec *p = NULL;
871   short detail;
872   ximChangeICReq req;
873   ximICValuesReq ic_req;
874   ximICAttributesReq pre_req, st_req;
875   ximEventReply reply;
876   int error = 0, ret, cur_is_world = 0;
877 
878   if (EACH_REQUEST (&req, sz_ximChangeICReq) == -1)
879     return;
880   if (need_byteswap () == True)
881     {
882       req.xic = byteswap_l (req.xic);
883     }
884 
885   if (_ReadFromClient (&ic_req, sz_ximICValuesReq) == -1)
886     return;
887   if (need_byteswap () == True)
888     {
889       byteswap_ICValuesReq (&ic_req);
890     }
891   if ((ret = read_strings (&use_langs, &use_langs_len, ic_req.nbytes)) < 0)
892     {
893       if (ret == -1)
894         return;
895       error++;
896     }
897   if ((ret = read_strings (&cur_l, &cur_l_len, ic_req.nbytes2)) < 0)
898     {
899       if (ret == -1)
900         return;
901       error++;
902     }
903 
904   if (_ReadFromClient (&pre_req, sz_ximICAttributesReq) == -1)
905     return;
906   if (need_byteswap () == True)
907     {
908       byteswap_ICAttributesReq (&pre_req);
909     }
910   if ((ret = read_strings (&pre_font, &pre_font_len, pre_req.nbytes)) < 0)
911     {
912       if (ret == -1)
913         return;
914       error++;
915     }
916 
917   if (_ReadFromClient (&st_req, sz_ximICAttributesReq) == -1)
918     return;
919   if (need_byteswap () == True)
920     {
921       byteswap_ICAttributesReq (&st_req);
922     }
923   if ((ret = read_strings (&st_font, &st_font_len, st_req.nbytes)) < 0)
924     {
925       if (ret == -1)
926         return;
927       error++;
928     }
929   if (error > 0)
930     {
931       reply.state = -1;
932       reply.detail = AllocError;
933       goto ERROR_RET;
934     }
935 
936   for (xc = ximclient_list; xc != NULL; xc = xc->next)
937     {
938       if (xc->number == req.xic)
939         break;
940     }
941   if (xc == NULL)
942     {
943       reply.state = -1;
944       reply.detail = BadIC;
945     }
946   else
947     {
948       if (cur_l && *cur_l)
949         {
950           if ((cur_is_world = get_langlist (cur_l, &p)) < 0)
951             {
952               reply.state = -1;
953               reply.detail = AllocError;
954               goto ERROR_RET;
955             }
956         }
957       if (change_client (xc, &ic_req, &pre_req, &st_req, p, cur_is_world, pre_font, st_font, &detail) == -1)
958         {
959           reply.state = -1;
960           reply.detail = detail;
961         }
962       else
963         {
964           reply.state = 0;
965           reply.detail = 0;
966         }
967       if (p)
968         free_langlist (p);
969     }
970 ERROR_RET:
971   if (need_byteswap () == True)
972     {
973       byteswap_EventReply (&reply);
974     }
975   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
976     return;
977   return;
978 }
979 
980 void
981 DestroyIC ()
982 {
983   ximDestroyICReq req;
984   ximEventReply reply;
985   register XIMClientRec *xc;
986 
987   if (EACH_REQUEST (&req, sz_ximDestroyICReq) == -1)
988     return;
989   if (need_byteswap () == True)
990     {
991       req.xic = byteswap_l (req.xic);
992     }
993 
994   for (xc = ximclient_list; xc != NULL; xc = xc->next)
995     {
996       if (xc->number == req.xic)
997         break;
998     }
999   if (xc == NULL)
1000     {
1001       reply.state = -1;
1002       reply.detail = BadIC;
1003     }
1004   else
1005     {
1006       reply.state = 0;
1007       reply.detail = 0;
1008     }
1009   if (need_byteswap () == True)
1010     {
1011       byteswap_EventReply (&reply);
1012     }
1013   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
1014     return;
1015   if (xc)
1016     {
1017       (void) destroy_client (xc);
1018     }
1019   return;
1020 }
1021 
1022 void
1023 destroy_for_sock (fd)
1024      int fd;
1025 {
1026   register XIMClientRec *xc;
1027 
1028   for (xc = ximclient_list; xc != NULL; xc = xc->next)
1029     {
1030       if (xc->fd == fd)
1031         {
1032           (void) destroy_client (xc);
1033 /*
1034             break;
1035 */
1036         }
1037     }
1038 }
1039 
1040 void
1041 destroy_xl (xc, xl)
1042      register XIMClientRec *xc;
1043      register XIMLangRec *xl;
1044 {
1045   remove_locale_to_xl (xl, NULL);
1046 #ifdef X11R5
1047   if (xl->xlc)
1048     XFree ((char *) xl->xlc);
1049 #endif /* X11R5 */
1050   if (!(IsPreeditNothing (xc)))
1051     {
1052       if (IsPreeditArea (xc))
1053         {
1054           XDestroyWindow (dpy, xl->wp[0]);
1055         }
1056       else if (IsPreeditPosition (xc))
1057         {
1058           XDestroyWindow (dpy, xl->wp[0]);
1059           XDestroyWindow (dpy, xl->wp[1]);
1060           XDestroyWindow (dpy, xl->wp[2]);
1061           XDestroyWindow (dpy, xl->wn[0]);
1062           XDestroyWindow (dpy, xl->wn[1]);
1063           XDestroyWindow (dpy, xl->wn[2]);
1064         }
1065       if (xl->pe_fs)
1066         XFreeFontSet (dpy, xl->pe_fs);
1067       if (xl->pe_b_char)
1068         Free ((char *) xl->pe_b_char);
1069       del_client (xl->w_c, 0);
1070       Free ((char *) xl->buf);
1071     }
1072   if (!(IsStatusNothing (xc)))
1073     {
1074       if (IsStatusArea (xc))
1075         {
1076           XDestroyWindow (dpy, xl->ws);
1077         }
1078       if (xl->st_fs)
1079         XFreeFontSet (dpy, xl->st_fs);
1080       if (xl->st_b_char)
1081         Free ((char *) xl->st_b_char);
1082       Free ((char *) xl->buf0);
1083     }
1084   Free ((char *) xl);
1085 }
1086 
1087 void
1088 destroy_client (xc)
1089      register XIMClientRec *xc;
1090 {
1091   register int i;
1092   register XIMInputRec *xi;
1093 
1094   if (cur_x && cur_x == xc)
1095     {
1096       if (
1097 #ifdef  CALLBACKS
1098            IsPreeditCallbacks (xc) ||
1099 #endif /* CALLBACKS */
1100            IsPreeditPosition (xc) || IsPreeditArea (xc))
1101         {
1102           invisual_window ();
1103         }
1104       if (!IsPreeditNothing (xc) && c_c->func_stack_count >= 0 && c_c->command_func_stack[c_c->func_stack_count] != 0)
1105         {
1106           (*c_c->command_func_stack[c_c->func_stack_count]) (-99);
1107         }
1108       cur_input = NULL;
1109       cur_x = NULL;
1110       cur_p = NULL;
1111       c_c = NULL;
1112     }
1113   for (xi = input_list; xi != NULL; xi = xi->next)
1114     {
1115       if (xi->pclient == xc)
1116         {
1117           remove_inputlist (xi);
1118           if (cur_input == xi)
1119             cur_input = NULL;
1120           Free ((char *) xi);
1121         }
1122     }
1123   for (i = 0; i < xc->lang_num; i++)
1124     {
1125       destroy_xl (xc, xc->xl[i]);
1126     }
1127   remove_ximclientlist (xc);
1128   if (xc->yes_no)
1129     {
1130       remove_box (xc->yes_no->title);
1131       remove_box (xc->yes_no->button[0]);
1132       remove_box (xc->yes_no->button[1]);
1133       Free ((char *) xc->yes_no);
1134     }
1135   if (xc->using_language)
1136     Free ((char *) xc->using_language);
1137   if (xc->user_name)
1138     Free ((char *) xc->user_name);
1139   if (xc->pe.fontset)
1140     Free ((char *) xc->pe.fontset);
1141   if (xc->st.fontset)
1142     Free ((char *) xc->st.fontset);
1143   if (xc->pe.gc)
1144     XFreeGC (dpy, xc->pe.gc);
1145   if (xc->pe.invertgc)
1146     XFreeGC (dpy, xc->pe.invertgc);
1147   if (xc->pe.reversegc)
1148     XFreeGC (dpy, xc->pe.reversegc);
1149   if (xc->st.gc)
1150     XFreeGC (dpy, xc->st.gc);
1151   if (xc->st.reversegc)
1152     XFreeGC (dpy, xc->st.reversegc);
1153   if (xc->xl)
1154     Free ((char *) xc->xl);
1155   if (IsPreeditNothing (xc))
1156     {
1157       check_root_mapping (xc->root_pointer);
1158     }
1159   Free ((char *) xc);
1160   return;
1161 }
1162 
1163 void
1164 ResetIC ()
1165 {
1166   ximResetICReq req;
1167   ximEventReply reply;
1168   register XIMClientRec *xc;
1169   WnnClientRec *save_c_c;
1170   XIMClientRec *save_cur_p, *save_cur_x;
1171   int ret;
1172 
1173   if (EACH_REQUEST (&req, sz_ximResetICReq) == -1)
1174     return;
1175   if (need_byteswap () == True)
1176     {
1177       req.xic = byteswap_l (req.xic);
1178     }
1179 
1180   for (xc = ximclient_list; xc != NULL; xc = xc->next)
1181     {
1182       if (xc->number == req.xic)
1183         break;
1184     }
1185   if (xc == NULL)
1186     {
1187       reply.state = -1;
1188       reply.detail = BadIC;
1189     }
1190   else
1191     {
1192       save_c_c = c_c;
1193       save_cur_p = cur_p;
1194       save_cur_x = cur_x;
1195       cur_x = xc;
1196       if (IsPreeditNothing (xc))
1197         {
1198           cur_p = xc->root_pointer->ximclient;
1199         }
1200       else
1201         {
1202           cur_p = cur_x;
1203         }
1204       c_c = cur_p->cur_xl->w_c;
1205       ret = reset_c_b ();
1206       JWMline_clear (0);
1207       c_c = save_c_c;
1208       cur_p = save_cur_p;
1209       cur_x = save_cur_x;
1210       if (ret == -1)
1211         {
1212           reply.state = -1;
1213           reply.detail = BadIC;
1214         }
1215       else
1216         {
1217           reply.state = 0;
1218           reply.detail = 0;
1219         }
1220     }
1221   if (need_byteswap () == True)
1222     {
1223       byteswap_EventReply (&reply);
1224     }
1225   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
1226     return;
1227   return;
1228 }
1229 
1230 void
1231 free_langlist (p)
1232      register XIMNestLangList p;
1233 {
1234   register XIMNestLangList n;
1235   for (; p != NULL; p = n)
1236     {
1237       n = p->next;
1238       Free ((char *) p);
1239     }
1240 }
1241 
1242 int
1243 get_langlist (lang, nl)
1244      char *lang;
1245      XIMNestLangList *nl;
1246 {
1247   register char *d, *save_d, *p, *alloc, *next;
1248   register int alias_name_len, lc_name_len, have_world = 0;
1249   register XIMNestLangList pp = NULL, prev = NULL, ls;
1250   XIMNestLangList w_ls;
1251   register XIMLcNameRec *lnl;
1252 
1253   *nl = NULL;
1254   if (lang == NULL || *lang == '\0')
1255     return (0);
1256   if (!(save_d = d = alloc_and_copy (lang)))
1257     return (-1);
1258   for (;;)
1259     {
1260       if (p = index ((p = d), ';'))
1261         {
1262           *p = '\0';
1263           next = ++p;
1264         }
1265       else
1266         {
1267           next = NULL;
1268         }
1269       if (p = index ((p = d), ','))
1270         {
1271           *(p++) = '\0';
1272           alias_name_len = strlen (p);
1273         }
1274       else
1275         {
1276           alias_name_len = 0;
1277         }
1278       lc_name_len = strlen (d);
1279 
1280       if (!strcmp (world_locale, d))
1281         {
1282           have_world++;
1283           d = next;
1284           if (!d)
1285             break;
1286           continue;
1287         }
1288       for (lnl = lc_name_list; lnl; lnl = lnl->next)
1289         {
1290           if (!strcmp (lnl->lc_name, d))
1291             break;
1292         }
1293       if (!lnl)
1294         {
1295           print_out1 ("I don't support such locale \"%s\".", d);
1296           d = next;
1297           if (!d)
1298             break;
1299           continue;
1300         }
1301       if (!(alloc = Calloc (1, (sizeof (XIMNestLangRec) + lc_name_len + alias_name_len + 2))))
1302         {
1303           malloc_error ("allocation langlist struct");
1304           return (-1);
1305         }
1306       ls = (XIMNestLangList) alloc;
1307       alloc += sizeof (XIMNestLangRec);
1308       ls->lc_name = alloc;
1309       strcpy (ls->lc_name, d);
1310       alloc += lc_name_len + 1;
1311       if (alias_name_len > 0)
1312         {
1313           ls->alias_name = alloc;
1314           strcpy (ls->alias_name, p);
1315         }
1316       ls->lang_db = lnl->lang_db;
1317       if (prev == NULL)
1318         {
1319           pp = ls;
1320         }
1321       else
1322         {
1323           prev->next = ls;
1324         }
1325       prev = ls;
1326       ls->next = NULL;
1327       d = next;
1328       if (!d)
1329         break;
1330     }
1331   Free (save_d);
1332   if (have_world)
1333     {
1334       if (get_langlist (world_lang, &w_ls) < 0)
1335         return (-1);
1336       if (w_ls)
1337         {
1338           if (pp)
1339             {
1340               ls->next = w_ls;
1341             }
1342           else
1343             {
1344               pp = w_ls;
1345               have_world++;
1346             }
1347         }
1348       else
1349         {
1350           have_world = 0;
1351         }
1352     }
1353   *nl = pp;
1354   return (have_world);
1355 }
1356 
1357 #ifdef SPOT
1358 void
1359 ChangeSpot ()
1360 {
1361   register XIMClientRec *xc;
1362   ximChangeSpotReq req;
1363   ximEventReply reply;
1364 
1365   if (EACH_REQUEST (&req, sz_ximChangeSpotReq) == -1)
1366     return;
1367   if (need_byteswap () == True)
1368     {
1369       req.xic = byteswap_l (req.xic);
1370       req.spot_x = byteswap_s (req.spot_x);
1371       req.spot_y = byteswap_s (req.spot_y);
1372     }
1373 
1374   for (xc = ximclient_list; xc != NULL; xc = xc->next)
1375     {
1376       if (xc->number == req.xic)
1377         break;
1378     }
1379   if (xc == NULL)
1380     {
1381       reply.state = -1;
1382       reply.detail = BadIC;
1383     }
1384   else
1385     {
1386       if (change_spotlocation (xc, req.spot_x, req.spot_y) == -1)
1387         {
1388           reply.state = -1;
1389           reply.detail = 0;
1390         }
1391       else
1392         {
1393           reply.state = 0;
1394           reply.detail = 0;
1395         }
1396     }
1397   if (need_byteswap () == True)
1398     {
1399       byteswap_EventReply (&reply);
1400     }
1401   if ((_WriteToClient (&reply, sz_ximEventReply) == -1) || (_Send_Flush () == -1))
1402     return;
1403   return;
1404 }
1405 #endif /* SPOT */
1406